【发布时间】:2011-10-28 22:35:09
【问题描述】:
我有一个页面运行一系列exec() 命令,这些命令强制我的 PHP 脚本停止更改,直到收到响应。如何告诉exec() 不要等待响应而直接运行命令?
我正在使用一个复杂的命令,它有一个可以查询以检查状态的后端系统,所以我不关心响应。
【问题讨论】:
我有一个页面运行一系列exec() 命令,这些命令强制我的 PHP 脚本停止更改,直到收到响应。如何告诉exec() 不要等待响应而直接运行命令?
我正在使用一个复杂的命令,它有一个可以查询以检查状态的后端系统,所以我不关心响应。
【问题讨论】:
后台运行命令怎么样?
exec('./run &');
【讨论】:
exec 与 & 等 shell 元字符无关。这将简单地将 ./run 与参数 ['./run', '&'] 结合起来。
shell_exec 也在等待孩子退出。
exec('sleep 20 > /dev/null &'); 立即返回。
取决于您使用的平台,以及您正在运行的命令。
例如,在 Unix/Linux 上,您可以将> /dev/null & 附加到命令的末尾,以告诉 shell 释放您已启动的进程,并且 exec 将立即返回。这在 Windows 上不起作用,但有一种使用 COM 对象的替代方法(请参阅下面的编辑)。
许多命令都有一个可以传递的命令行参数,因此它们释放与终端的关联并立即返回。此外,一些命令会出现挂起,因为它们已经提出问题并等待用户输入告诉它们继续(例如,当运行 gzip 并且目标文件已经存在时)。在这些情况下,通常可以传递一个命令行参数来告诉程序如何处理这个问题而不是提出问题(在gzip 示例中,您将传递-f)。
编辑
只要COM 可用,以下是在 Windows 上执行所需操作的代码:
$commandToExec = 'somecommand.exe';
$wshShell = new COM("WScript.Shell");
$wshShell->Run($commandToExec, 0, FALSE);
请注意,它是第三个 FALSE 参数告诉 WshShell 启动程序然后立即返回(第二个 0 参数定义为“窗口样式”,在这里可能没有意义 - 你可以传递任何整数值)。 WshShell 对象记录在 here。这绝对有效,我以前用过...
我还在上面进行了编辑以反映这样一个事实,即为了让 & 在 *nix 上与 exec() 一起工作,还需要管道到 /dev/null。
还添加了有关 WshShell 的更多信息。
【讨论】:
在过去,我很幸运地使用了以下构造(windows,但我确信 *nix 中有一个等效的命令
pclose(popen('START /B some_command','r'));
【讨论】:
pclose(popen('START /B CMD /C START C:\php5\php.exe -c c:\Apache\Apache2.2\bin -f <filename>', 'r')); 的操作