如何停止服务产生的所有子进程

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 进程。

如何完全停止服务(即所有子进程都被杀死)?理想情况下,我不想修改上面的配置文件。

Jde*_*eBP 5

理想情况下,我不想修改上面的配置文件。

艰难的!这是正确的做法。

您需要将您更改execscript,并停止在分叉子进程中运行该 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)

进一步阅读


all*_*tic 3

在 GNU/Linux 上,通常无法停止服务及其生成的所有子进程,因为子进程可以更改其 PPID(父进程 ID)。唯一了解的方法是跟踪生成进程的系统调用,并保留这些进程的列表。

Ubuntu init 系统upstart不执行此操作。所以你的问题的答案是在 Ubuntu 上,如果没有:

  1. 修改该脚本;
  2. 确切地知道该进程生成了哪些进程 ID;
  3. 手动跟踪这些进程 ID;
  4. 单独杀死他们。

这就是为什么您应该运行运行systemd的 Linux 发行版。正如您所看到的,systemd跟踪所有子进程,并且可以使用单个命令杀死每个子进程。GNU/Linux 系统管理应该是这样的,但是因为 systemd 太新了,而且因为它是“Not Invented Here”(意思是 Canonical 没有发明它),所以 Ubuntu 不想使用它。