bash – 为什么cron产生的进程最终没有结束?

前端之家收集整理的这篇文章主要介绍了bash – 为什么cron产生的进程最终没有结束?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一些进程显示为<已停止>在顶部(和ps).我从真正的脚本和程序中煮了一些东西.

在我的crontab:

* * * * * /tmp/launcher.sh /tmp/tester.sh

launcher.sh的内容(当然标记为可执行文件):

#!/bin/bash
# the real script does a little argument processing here
"$@"

tester.sh的内容(当然可以标记为可执行文件):

#!/bin/bash
sleep 27 & # the real script launches a compiled C program in the background

ps显示如下:

user       24257 24256  0 18:32 ?        00:00:00 [launcher.sh] <defunct>
user       24259     1  0 18:32 ?        00:00:00 sleep 27

请注意,tester.sh不会出现 – 它在启动后台作业后退出.

为什么launcher.sh贴在周围,标记为< defunct>?它只是在cron启动时才会这样做 – 而不是当我自己运行时.

附加说明:launcher.sh是系统运行的常用脚本,不易修改.其他的东西(crontab,tester.sh,甚至我运行的程序,而不是睡眠)可以更容易地修改.

因为他们没有被等待(2)系统调用主题.

由于有人可能会等待这些进程在未来,内核不能完全摆脱它们,否则将无法执行等待系统调用,因为它不会有退出状态或其存在的证据.

当您从shell启动一个shell时,shell正在捕获SIGCHLD并进行各种等待操作,所以没有任何延迟.

但是,cron并没有处于等待状态,它正在睡觉,所以已故的孩子可能会坚持一段时间,直到cron醒来.

更新:回应评论
嗯.我没有设法复制这个问题:

PPID   PID  PGID  SESS COMMAND
    1  3562  3562  3562 cron
 3562  1629  3562  3562  \_ cron
 1629  1636  1636  1636      \_ sh <defunct>
    1  1639  1636  1636 sleep

所以,发生了什么事,我想:

cron fork和cron小孩启动shell
> shell(1636)启动sid和pgid 1636并开始睡眠
> shell出口,SIGCHLD发送到cron 3562
>信号被忽略或误操作
> shell转僵尸.注意,睡眠被重新设置为init,所以当睡眠退出init将得到信号并清理.我还在试图找出僵尸何时获得收获.可能没有活跃的孩子cron 1629可以退出,那时僵尸将被重新启动并获得收获.所以现在我们想知道cron应该处理的缺失的SIGCHLD.>并不一定是cron的错误.正如你可以在这里看到的,libdaemon installs a SIGCHLD handler在daemon_fork()期间,这可能会干扰中间的快速退出的信号传递1629Now,我甚至不知道我的Ubuntu系统上的vixie cron是否甚至使用libdaemon构建,但至少我有一个新的理论.

猜你在找的Bash相关文章