杀死守护进程的所有子进程

时间:2012-09-04 13:46:45

标签: bash subprocess kill init.d lsb

我正在撰写/etc/init.d/mydaemon

# ...
source functions # LSB compliant 

EXEC=/usr/local/bin/mydaemon
PROG=mydaemon

function start() {
  daemon --pidfile=/var/run/mydeamon.pid ${EXEC}
}

function stop() {
  killproc ${PROG}
}

# ...

我的/usr/local/bin/mydaemon

#!/bin/bash
trap "trap TERM ; kill 0" TERM
binary with some args

AFAIK,这应该有效,因为:

  • daemonmydaemon
  • 中记录/var/run/mydaemon.pid的PID
  • killproc读取该PID并将SIGTERM发送到该PID。
  • mydaemon捕获此信号,停用陷阱并将SIGTERM发送到整个PGRP,包括binary with some args的过程。

然而,这不起作用。停止服务后,mydaemon终止,但binary仍在运行。

我错过了什么,停止守护进程及其所有守护进程的最佳做法是什么?孩子吗


顺便说一句:

当我的/ usr / local / bin / mydaemon是:

#!/bin/bash
binary with some args &
echo $! $$ > /var/run/mydaemon.pid
wait

它运行正常,但这对我来说似乎不太健壮,有时候这是不合适的(当二进制调用不太直接,或者它有自己的孩子等)时。

3 个答案:

答案 0 :(得分:2)

如果你将父进程的id赋予pkill,它会杀死所有的孩子:

pkill -TERM -P parentID

答案 1 :(得分:1)

对于问题中提出的特定情况,也值得考虑为/usr/local/bin/mydaemon使用以下选项:

#!/bin/bash
exec binary with some args

binary而不是在具有新PID的子进程中运行,而是将接管Shell进程PID,从而直接从init脚本接收信号。

答案 2 :(得分:0)

您可以设置trap,在收到SIGINT时负责清理过程。例如:

function cleanup { kill $CHILDPID; exit 0; }
trap cleanup SIGINT SIGTERM

有关更多示例,请参阅here