【问题标题】:kill all subprocesses of a daemon杀死一个守护进程的所有子进程
【发布时间】:2012-09-04 13:46:45
【问题描述】:

我正在写/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,这应该可行,因为:

  • daemon 在/var/run/mydaemon.pid 中记录mydaemon 的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

它可以正常工作,但这对我来说似乎不太健壮,而且有时这是不合适的(当二进制调用不那么直接,或者它有自己的孩子时,等等)。

【问题讨论】:

    标签: bash subprocess kill init.d lsb


    【解决方案1】:

    如果你把父进程的 id 给 pkill,它会杀死所有的子进程:

    pkill -TERM -P parentID
    

    【讨论】:

      【解决方案2】:

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

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

      更多示例请参见here。

      【讨论】:

        【解决方案3】:

        对于问题中提出的具体场景,/usr/local/bin/mydaemon 的以下选项也值得考虑:

        #!/bin/bash
        exec binary with some args
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-06-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-30
          相关资源
          最近更新 更多