gpt4 book ai didi

php - 疯狂的 crond 行为。不断制作失效的 bash 进程

转载 作者:太空宇宙 更新时间:2023-11-03 17:17:45 24 4
gpt4 key购买 nike

我有一个 crontab,看起来像:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

0-59 * * * * /var/www/html/private/fivemin/zdaemon.php >> /dev/null &

越简单越好,对吧?

我正在测试的 zdaemon.php 是:

#!/usr/bin/php
<?


while(true){
sleep(1);
}

?>

无论何时运行,它都会像这样挂起:

root     15532  0.0  0.1 57228 1076 ?        Ss   19:09   0:00 crond
root 16681 0.0 0.1 72196 1428 ? S 21:46 0:00 crond
root 16682 0.0 0.0 0 0 ? Zs 21:46 0:00 [bash] <defunct>
root 16683 0.0 0.5 54800 5740 ? S 21:46 0:00 /usr/bin/php /var/www/html/private/fivemin/zdaemon.php
root 16687 0.0 0.1 72196 1428 ? S 21:47 0:00 crond
root 16688 0.0 0.0 0 0 ? Zs 21:47 0:00 [bash] <defunct>
root 16689 0.0 0.5 54800 5740 ? S 21:47 0:00 /usr/bin/php /var/www/html/private/fivemin/zdaemon.php

我整天都在为这件事绞尽脑汁。有没有人见过这个?有什么想法吗?

这是对:Init.d script hanging 的引用

最佳答案

僵尸 进程本身并不一定是坏事。它表明 child 进程已经死亡,parent 进程还没有获得它的状态(使用 wait() 或相关的系统调用).

发生的事情如下 - cron 对它启动的脚本中的 stderr 感兴趣(这样它可以在脚本失败时通过电子邮件将其发送给您),因此它创建了一个 pipe,它附加了脚本的 stderr 到写端(文件描述符 2)。然后 cron 坐在管道的读取端读取,等待脚本退出并读取 eof (零字节的 read()) - 然后它获取脚本的返回状态。

在您的示例中,生成的守护程序继承了 stderr 文件描述符,因此当中间 shell 退出(并失效)时,管道将由守护程序保持打开状态。因此,cron 从不读取 eof,因此从不获取返回状态。

解决方案是确保您的守护程序的 stderr 已关闭。这可以通过以下方式实现:

0-59 * * * * /var/www/html/private/fivemin/zdaemon.php >> /dev/null 2>&1 &

这会将 stdoutstderr 写入 /dev/null

关于php - 疯狂的 crond 行为。不断制作失效的 bash 进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3748432/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com