Intereting Posts

Безумное поведение когтей. продолжает отменять процессы bash

У меня есть 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); } ?> в #!/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

Процесс зомби не обязательно плох сам по себе. Он указывает, что дочерний процесс умер, а родительский процесс еще не получил свой статус (используя wait() или соответствующий системный вызов).

То, что происходит, выглядит следующим образом: cron интересуется stderr от запуска скрипта (чтобы он мог отправить его по электронной почте вам, если скрипт завершился с ошибкой), поэтому он создает канал, который прикрепляет stderr скрипта к концу записи (дескриптор файла 2). Затем cron сидит на считываемом конце трубы, ожидая выхода скрипта и чтения eof ( read() из нулевых байтов), после чего он возвращает статус возврата сценария.

В вашем примере демона, порожденного, наследует дескриптор файла stderr , и поэтому, когда промежуточная оболочка выходит (и перестает функционировать), канал удерживается открытым демоном. Поэтому cron никогда не читает eof и, следовательно, никогда не получает статус возврата.

Решение состоит в том, чтобы закрыть stderr вашего демона. Это может быть достигнуто следующим образом:

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

который будет записывать как stdout, так и stderr в /dev/null

Я думаю, что ваша главная проблема заключается в том, что stderr все еще идет в оболочку, но дочерний процесс (ваш php-процесс) спал, в результате чего происходит процесс зомби. Попробуй это:

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

Если у вас все еще возникают проблемы с зомби-процессом, взгляните на nohup .

Мне кажется странным, что я занимаюсь процессом в кронтабе. Попробуйте удалить & в конце строки.

Обычным способом создания демона является разветвление дочернего процесса для выполнения работы, а затем выход из родительского процесса с кодом ошибки 0. Я не знаю точно, что это ваша проблема.

Я не делал этого в php, но вы могли бы использовать pcntl_fork (), чтобы имитировать обычный c-путь .