Dha*_*ara 6 linux services ubuntu
我有一个在 Ubuntu 上运行的服务,配置如下:
#/etc/init/my_service.conf
start on (local-filesystems and net-device-up IFACE=eth1)
respawn
exec python -u /opt/XYZ/my_prog.py 2>&1 \
| logger -t my_prog.py
Run Code Online (Sandbox Code Playgroud)
使用 停止服务时sudo service my_service stop,python 进程不会被终止。杀死父进程kill也不会杀死 python 进程。
如何完全停止服务(即所有子进程都被杀死)?理想情况下,我不想修改上面的配置文件。
理想情况下,我不想修改上面的配置文件。
艰难的!这是正确的做法。
您需要将您更改exec为script,并停止在分叉子进程中运行该 python 程序作为管道的一部分。 此 ServerFault 答案解释了如何在嵌入式 shell 脚本中执行此操作。我只会对那里给出的脚本进行一次更改,在最后一行:
exec python -u /opt/XYZ/my_prog.py 2>&1
Run Code Online (Sandbox Code Playgroud)
毕竟,也没有很好的理由不记录标准错误。
更复杂的循环来应对分叉,从expect daemon到切换到systemd,错过了正确的做法是阻止守护进程分叉。如果说当前的混乱能带来一件好事,那就是不断确认 IBM 在 1995 年编写和推荐的内容这些年来一直是正确的。
习惯链加载守护进程的想法。有很多工具集可以让这些事情变得简单。也要习惯不使用 shell 脚本的想法。有许多专门为这项工作设计的工具集,它们消除了 shell 的开销(这在 Ubuntu 世界中是一个众所周知的好主意)。
例如:ServerFault 答案中的 shell 命令可以替换为使用Laurent Bercotexecline工具的脚本,这些工具旨在无需子 shell 和未链接的 FIFO 即可完成此操作:
#!/command/execlineb -PW
pipeline -w {
logger -t my_prog.py
}
fdmove -c 2 1
python -u /opt/XYZ/my_prog.py
Run Code Online (Sandbox Code Playgroud)
然后你会简单地
exec /foo/this_execlineb_script
Run Code Online (Sandbox Code Playgroud)
使用我的nosh工具集,它同样是一个包含以下内容的脚本:
#!/usr/local/bin/nosh
pipe
fdmove -c 2 1
python -u /opt/XYZ/my_prog.py | logger -t my_prog.py
Run Code Online (Sandbox Code Playgroud)
或者,您可以直接在 Upstart 作业定义中包含此节(使用一种技巧来避免 shell 元字符,以便 Upstart 不会产生 shell):
exec /usr/local/bin/exec pipe --separator SPLIT fdmove -c 2 1 python -u /opt/XYZ/my_prog.py SPLIT logger -t my_prog.py
Run Code Online (Sandbox Code Playgroud)
在 GNU/Linux 上,通常无法停止服务及其生成的所有子进程,因为子进程可以更改其 PPID(父进程 ID)。唯一了解的方法是跟踪生成进程的系统调用,并保留这些进程的列表。
Ubuntu init 系统upstart不执行此操作。所以你的问题的答案是,在 Ubuntu 上,如果没有:
这就是为什么您应该运行运行systemd的 Linux 发行版。正如您所看到的,systemd跟踪所有子进程,并且可以使用单个命令杀死每个子进程。GNU/Linux 系统管理应该是这样的,但是因为 systemd 太新了,而且因为它是“Not Invented Here”(意思是 Canonical 没有发明它),所以 Ubuntu 不想使用它。
| 归档时间: |
|
| 查看次数: |
8613 次 |
| 最近记录: |