PHP passthru()阻止进程替换

时间:2012-03-05 12:28:31

标签: php bash daemon io-redirection

当我应该启动一个守护进程时遇到PHP passthru()阻塞问题。

我有一个Node.js守护进程,其周围有一个bash脚本包装器。该bash脚本使用了一些进程替换,因为Node.js服务器无法直接登录到syslog。 bash脚本包含如下命令:

forever -l app.log app.js

但是因为我想让它登录到syslog,我使用:

forever -l >(logger) app.js

logger进程替换创建了一个文件描述符,如/dev/fd/63,其路径作为要使用的日志文件传递给forever命令。

当我直接使用bash脚本启动守护进程时,这很有用,但是当使用PHP passthru()或exec()执行bash脚本时,这些调用将会阻塞。如果我使用常规日志文件而不是进程替换,那么passthru()和exec()都可以正常工作,在后台启动守护进程。

我在Github的Gist上创建了一个完整的工作示例(使用简单的PHP守护进程而不是Node.js):https://gist.github.com/1977896(需要PHP 5.3.6 +)

为什么passthru()调用阻止进程替换?我能做些什么来解决它吗?

1 个答案:

答案 0 :(得分:0)

即使你启动一个守护进程,

passthru()也会在PHP中阻塞,这很不幸。我听说有些人有运气用nohup重写它:

exec('/path/to/cmd');

然后变成:

exec('nohup /path/to/cmd &');

就个人而言,我最幸运的是exec()使用wget exec来调用另一个脚本(或相同的脚本)来实际运行阻塞exec。通过将调用进程提供给与实时用户无关的另一个http进程,可以解除调用进程的阻塞。使用适当的标志,wget将立即返回,而不是等待响应:

exec('wget --quiet --tries=1 -O - --timeout=1 --no-cache http://localhost/path/to/cmd');

http处理程序最终会超时,这应该可以让守护进程运行。如果您需要输出(因此您正在进行passthru()调用),只需运行脚本将输出重定向到文件,然后轮询该文件以查看实时过程中的更改。