有没有办法在不等待命令完成的情况下使用shell_exec?

时间:2009-06-19 20:20:04

标签: php shell

我有一个过程密集型任务,我想在后台运行。

用户点击页面,PHP脚本运行,最后,根据某些条件,如果需要,则必须运行shell脚本,E.G。:

shell_exec('php measurePerformance.php 47 844 email@yahoo.com');

目前我使用shell_exec这需要脚本等待输出。有没有办法执行我想要的命令没有等待它完成?

9 个答案:

答案 0 :(得分:138)

如何添加。

"> /dev/null 2>/dev/null &"

shell_exec('php measurePerformance.php 47 844 email@yahoo.com > /dev/null 2>/dev/null &');

请注意,这也消除了stdio和stderr。

答案 1 :(得分:26)

这将执行命令并断开与正在运行的进程的连接。当然,它可以是您想要的任何命令。但是对于测试,你可以使用sleep(20)命令创建一个php文件。

exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");

答案 2 :(得分:11)

您也可以立即将输出返回给客户端,然后继续处理您的PHP代码。

这是我用于长时间等待Ajax调用的方法,这对客户端没有任何影响:

ob_end_clean();
ignore_user_abort();
ob_start();
header("Connection: close");
echo json_encode($out);
header("Content-Length: " . ob_get_length());
ob_end_flush();
flush();
// execute your command here. client will not wait for response, it already has one above.

您可以在此处找到详细说明:http://oytun.co/response-now-process-later

答案 3 :(得分:8)

在Windows 2003上,为了在不等待的情况下调用另一个脚本,我使用了这个:

$commandString = "start /b c:\\php\\php.EXE C:\\Inetpub\\wwwroot\\mysite.com\\phpforktest.php --passmsg=$testmsg"; 
pclose(popen($commandString, 'r'));

仅在cmd.exe更改权限后才有效 - 为IUSR_YOURMACHINE添加读取和执行(我也设置写入拒绝)。

答案 4 :(得分:6)

使用PHP的popen命令,例如:

pclose(popen("start c:\wamp\bin\php.exe c:\wamp\www\script.php","r"));

这将创建一个子进程,脚本将在后台执行而无需等待输出。

答案 5 :(得分:6)

当然,对于windows,您可以使用:

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:/path/to/php-win.exe -f C:/path/to/script.php", 0, false);

注意:

如果您收到COM错误,请将扩展程序添加到php.ini并重新启动apache

[COM_DOT_NET]
extension=php_com_dotnet.dll

答案 6 :(得分:1)

如果它不在网页上,我建议生成某种信号(可能在目录中删除文件)并让cron作业完成需要完成的工作。否则,我们可能会进入在Apache进程内使用pcntl_fork()exec()的领域,这只是糟糕的事情。

答案 7 :(得分:1)

这样可以工作,但是你必须小心不要重载服务器,因为每次调用这个将在后台运行的函数时它都会创建一个新进程。如果同时只有一个并发呼叫,则此解决方法将完成此任务。

如果没有,那么我建议运行一个消息队列,例如beanstalkd / gearman / amazon sqs。

答案 8 :(得分:-3)

您总是可以将一些AJAX发布到调用shell_exec()的页面。