У меня есть короткий скрипт утилиты php, я запускаю его из cli просто:
php myscript.php
Сценарий всегда работает, периодически выполняя некоторые задачи (не относящиеся к вопросу). Он не требует ввода от пользователя. После запуска я обычно нажимаю CTRL + z, а затем запускаю bg
чтобы установить процесс в фоновом режиме, и все в порядке.
Если я запустил его как:
php myscript.php &
сценарий ставится на фон при запуске, но он также помещается в состояние остановки. Пример:
[1] 11513 [1]+ Stopped php myscript.php
даже запуск bg
в этот момент не помогает, мне нужно запустить fg
, затем CTRL + z и bg
снова, чтобы заставить его работать.
Это скрипт php:
<? while(true){ echo 'hi '.time()."\n"; sleep(30); } ?>
в<? while(true){ echo 'hi '.time()."\n"; sleep(30); } ?>
Моя проблема в том, что я не могу запустить его прямо в фоновом режиме, потому что система останавливает его, и я не понимаю, почему. Как я могу это исправить?
Обновить:
Я сделал версию bash одного и того же скрипта, и ее можно запустить и поместить в фоновом режиме (запустить и не остановить ), просто запустив ее с помощью & в конце ( script.sh &
)
script.sh:
#!/bin/bash while true; do echo `date` sleep 30 done
Почему скрипт php останавливается после его запуска в фоновом режиме, а сценарий bash – нет? Что может вызвать это другое поведение?
Как правило, процесс, который вы отправляете на задний план с помощью &
и сценария, ожидающего ввода с терминала, переходит в состояние остановки.
Например, скрипт bash valecho
:
#!/bin/sh read val echo $val
runnig это как:
./valecho &
сценарий остановится.
Когда запустите его как
echo hello | ./valecho &
будет правильно запускаться и заканчиваться.
Итак, проверьте ваш php – возможно, хочет получить какой-либо ввод от stdin
Изменить – на основе комментария:
я не разработчик php, но просто попробовал следующий скрипт ( p.php
)
<?php while(true){ echo 'hi '.time()."\n"; sleep(3); } ?>
в<?php while(true){ echo 'hi '.time()."\n"; sleep(3); } ?>
с командой:
php -f p.php &
и бегать красиво … так … жаль для путаницы …
Я обнаружил, что вызывает проблему. В PHP, если модуль readline включен, любой скрипт командной строки ожидает ввода, даже если скрипт написан НЕ, чтобы ждать ввода пользователя.
Чтобы проверить, включена ли поддержка чтения, просто запустите:
php --info |grep "Readline Support"
и проверьте выход. Если вы получаете Readline Support => enabled
тогда у вас включен режим чтения, и вы можете столкнуться с проблемой, описанной в исходном вопросе.
Правильный способ использования cli тогда, когда явным образом укажу, что php не использует терминал для ввода:
php myscript.php < /dev/null &
Дополнительная информация: http://php.net/manual/en/book.readline.php
Альтернативы:
./test.php >/dev/null &
или (более творческий):
nohup php test.php > /dev/null 2>&1 &
(ps: Я все еще верю, что этот вопрос относится к ServerFault, btw .. проблема решена!)
С http://php.net/manual/en/book.readline.php :
Когда readline включен, php переключает режим терминала, чтобы принять ввод с буферизацией. Это означает, что правильный способ использования cli при подключении к интерактивной команде – явно указать, что php не использует терминал для ввода:
php myscript.php < /dev/null &
источник