1

我正在写一个/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将的 PID记录在/var/run/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

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

4

3 回答 3

3

如果您将父进程的 id 提供给 pkill,它将杀死所有子进程:

pkill -TERM -P parentID
于 2012-09-04T13:59:43.823 回答
1

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

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

有关更多示例,请参见此处

于 2012-09-04T14:01:18.553 回答
1

对于问题中提出的具体情况,还值得考虑以下选项/usr/local/bin/mydaemon

#!/bin/bash
exec binary with some args

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

于 2020-11-19T05:25:07.850 回答