start-stop-daemon 使用错误的 pid 生成 cron pidfile

try*_*tch 4 cron services pidfile

我有一个 init.d 脚本来启动 crond,它为 start() 指定以下内容:

start-stop-daemon -S --quiet --make-pidfile --pidfile /var/run/crond.pid --background --exec /usr/sbin/crond
Run Code Online (Sandbox Code Playgroud)

但是,PID始终比 /var/run/crond.pid 中记录的数字高一个数字。有谁知道这里发生了什么?我有大约十个其他 init.d 脚本也进行相同的调用,只有 cron.d 有这个问题。

编辑: 这很有趣:

# /usr/sbin/crond &
#
[1]+  Done                       /usr/sbin/crond
# echo $!
737
# ps -eaf | grep crond
738 root     /usr/sbin/crond
740 root     grep crond
#
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 5

crond程序被设计为守护进程。当它启动时,它做的第一件事就是派生一个孩子并退出父母。这是为调用者在继续之前等待程序退出而守护进程需要在后台继续执行的环境而设计的。

caller ---- fork--> wait -------------------------+-> ...
             |                                    |
             '----> exec crond ---- fork--> exit -'
                                     |
                                     '----> read crontab, wait for time of next job, ...
Run Code Online (Sandbox Code Playgroud)

PID 记录的 start-stop-daemon的PID是父级的PID。如果在两次 fork 之间的短暂间隔内没有其他进程 fork,则 child 的 PID 最终是 parent 的 PID 加一。

由于start-stop-daemon旨在处理守护进程并让它们在后台运行,因此告诉crond保持在前台,即不要在开始时分叉。

caller ---- fork--> store pid; ...
             |                                    |
             '----> exec crond -f ----> read crontab, wait for time of next job, ...
Run Code Online (Sandbox Code Playgroud)

使用 BusyBox 的 crond,将-f选项传递给它。

start-stop-daemon -S --quiet --make-pidfile --pidfile /var/run/crond.pid --background --exec /usr/sbin/crond -- -f
Run Code Online (Sandbox Code Playgroud)