linux 启动脚本 /etc/init 与特定用户

linux 启动脚本 /etc/init 与特定用户

我在 /etc/init/mms-agent.conf 中创建了一个脚本:

start on runlevel [2345]
stop on runlevel [06]

exec /usr/bin/env python /home/mms/mms-agent/agent.py >> /home/mms/agent.log 2>&1

服务彩信代理启动/停止工作正常,但我想用用户“彩信”启动此服务

当我尝试按如下方式更改脚本时:

exec su mms -c "/usr/bin/env python /home/mms/mms-agent/agent.py >> /home/mms/agent.log 2>&1"

我运行了 3 个进程,而不是预期的 1 个(su、bash + 我的 python 脚本):

mms       8864  0.0  0.2  37816  1332 ?        Ss   22:30   0:00 su mms -c /usr/bin/env python /home/mms/mms-agent/agent.py >> /home/mms/agent.log 2>&1
mms       8865  0.0  0.2  11452  1196 ?        S    22:30   0:00 bash -c /usr/bin/env python /home/mms/mms-agent/agent.py >> /home/mms/agent.log 2>&1
mms       8866  4.0  1.8  54672 10640 ?        Sl   22:30   0:00 python /home/mms/mms-agent/agent.py

这意味着什么 ?

使用 root 以外的用户启动脚本的最佳方法是什么?

谢谢

附:

exec start-stop-daemon --start -u mms --exec "/usr/bin/env python /home/mms/mms-agent/agent.py"

不起作用,我没有收到错误,但该过程尚未启动。

答案1

以不同用户身份运行作业在Upstart手册中。使用start-stop-daemon是推荐的方法。

您刚刚犯了一个小错误:您传递了整个命令行,其中start-stop-daemon需要可执行文件的路径。分别传递参数。

调用的另一个问题是您告诉start-stop-daemon将任何 Python 进程视为您的服务的实例。这可能会导致它杀死其他不相关的 Python 进程。为确保您的服务仅运行一个实例,请使用 pidfile。

exec start-stop-daemon --start -c mms -u mms -m -p /var/run/mms-agent.pid \
                       --startas /usr/bin/env -- python /home/mms/mms-agent/agent.py

答案2

当您执行 exec 时su,外壳将被进程替换susu然后 forks 和 execs bashbash设置输出重定向,然后 forks 和 execs envenv搜索 PATH,找到python并执行它。因此,您剩下三个进程, 1) su,等待bash退出, 2) bash,等待python(之前env)退出,以及 3) python,它正在忙于运行您的脚本。

这并没有什么问题。 su是 Unix 历史悠久的临时切换用户的方法,所以这就是您应该使用的方法。同样,运行命令行的方式是使用 shell,所以su运行bash并让bash处理它。同样,这遵循通用的 Unix 工具箱方法,让 shell 做它擅长的事情,而不是在另一个应用程序中重新发明 shell 命令行和 PATH 搜索功能。

另外,由于bash已经进行了 PATH 搜索,因此您可以放弃使用env并直接调用python

答案3

您会得到三个进程,因为您正在运行 su,它会启动一个 shell 来运行 python 进程。

有多种方法可以让“额外”的两个进程相信它们可以退出,例如,您可以使用 python 脚本 fork 和 exec,或者可以使用 su 后台本身执行命令。

相关内容