在后台运行的命令行脚本处于停止状态

我有一个简短的PHP实用程序脚本,我只是用cli来运行它:

php myscript.php 

脚本始终在运行,定期执行一些任务(与问题无关)。 它不需要用户的任何input。 运行后,我通常按CTRL + Z ,然后运行bg将进程置于后台,一切正常。

如果我运行它:

 php myscript.php & 

脚本在启动时放在后台,但也处于停止状态。 例:

 [1] 11513 [1]+ Stopped php myscript.php 

即使运行bg在这一点上没有帮助,我必须运行fg ,然后CTRL + Zbg再次使其工作。

这是PHP脚本:

 <? 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 

运行它为:

 ./valecho & 

脚本将停止。

当运行它

 echo hello | ./valecho & 

将正确运行并完成。

所以,检查你的PHP – 可能要从stdin输入的一些输入

编辑 – 基于评论:

我不是一个PHP开发人员 – 但只是尝试下一个脚本( p.php

 <?php while(true){  echo 'hi '.time()."\n";  sleep(3); } ?> 

用命令:

 php -f p.php & 

并且运行得很好…所以…为了混淆…

我发现是什么导致了这个问题。 在PHP中,如果启用了readline模块,任何命令行脚本都会期待输入,即使写入脚本不等待用户输入。

要检查是否启用了readline支持,只需运行:

 php --info |grep "Readline Support" 

并检查输出。 如果您Readline Support => enabled readline,您可能会遇到原始问题中描述的问题。

当使用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,顺便说一句,问题解决了!)

http://php.net/manual/en/book.readline.php

当readline被启用时,php将终端模式切换为接受线路缓冲输入。 这意味着当您管道交互式命令时,使用cli的正确方法是明确指定php不使用终端进行输入:

 php myscript.php < /dev/null & 

资源