我在 /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
,外壳将被进程替换su
。 su
然后 forks 和 execs bash
。 bash
设置输出重定向,然后 forks 和 execs env
。 env
搜索 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 后台本身执行命令。