php exec命令(或类似命令)不等待结果


74

我有一个要运行的命令,但我不希望PHP坐下来等待结果。

<?php
echo "Starting Script";
exec('run_baby_run');
echo "Thanks, Script is running in background";
?>

是否有可能使PHP不等待结果..即,只需将其启动并移至下一个命令即可。

我找不到任何东西,甚至不确定是否有可能。我所能找到的最好的方法是,有人在一分钟内开始执行CRON工作。


1
如果您必须经常执行此操作,则可能还对JobQueue感兴趣,例如Gearman
哥顿(Gordon)2010年

Answers:


129

文档中

为了执行命令并使其在
运行时不挂起PHP脚本,所运行的程序不得输出回PHP。为此,
将stdout和stderr都重定向到/ dev / null,然后将其后台。

> /dev/null 2>&1 &

为了执行命令并将
其作为另一个
不依赖于Apache线程
继续运行的进程(如果
有人取消页面,它不会死亡)而产生:

exec('bash -c "exec nohup setsid your_command > /dev/null 2>&1 &"');


2
非常感谢!有许多“解决方案”实际上并不起作用(主浏览器线程仍在等待)。许多解决方案仅在末尾讲出“&”,这还不够。就是说,对我来说,一个更简单的解决方案可用于:exec('nohup your_command> / dev / null 2>&1&')就足够了。
Vincent Pazeller

您为什么还不需要移植stdin到/ dev / null?链接到shell的进程输入是否足以阻止nohup“放弃”子进程?(他们的stdin答案确实有所改变:superuser.com/questions/178587/…
NHDaly 2013年

另外,为什么同时调用nohupsetsid?我不能找到太多有关哪一个是好还是它们不同之处。(stackoverflow.com/questions/10247721/...
NHDaly

@Christin:您的解决方案正在解决我的问题:stackoverflow.com/questions/25700904/…您能回答这个问题吗?然后,我可以用绿色答案结束该问题。
sugunan 2014年

@Christin:能否请您看看我的问题似乎同我的问题:stackoverflow.com/questions/35331958/...
困惑男孩

52

您可以在后台运行命令,方法是在命令&末尾添加a :

exec('run_baby_run &');

但是单独执行此操作将挂起脚本,因为:

如果使用exec函数启动程序,则要使其在后台继续运行,必须将程序的输出重定向到文件或其他输出流。否则,PHP会挂起,直到程序执行结束。

因此,如果您想稍后再查看该命令或将/dev/null其丢弃为以下命令,可以将命令的标准输出重定向到文件:

exec('run_baby_run > /dev/null &');

1
不重定向stderr,并被崩溃的网络服务器杀死。
Cees Timmerman

9

它使用wget通知URL某些内容而无需等待。

$command = 'wget -qO- http://test.com/data=data';
exec('nohup ' . $command . ' >> /dev/null 2>&1 & echo $!', $pid);

它使用ls来更新日志,而无需等待。

$command = 'ls -la > content.log';
exec('nohup ' . $command . ' >> /dev/null 2>&1 & echo $!', $pid);

3
我认为您&2>&1和之间缺少符号echo,对吗?
圣地亚哥亚利桑那州

2
如果父母被杀,nohup还能使孩子继续奔跑吗?
Cees Timmerman

@santiagoarizti是的,我已将其修复,因为代码无法正常工作
Mr.Web

2

我知道已经回答了这个问题,但是在这里找到的答案不适用于我的方案(或Windows)。

我在Xampp v3.2.4中使用Windows 10笔记本电脑和PHP 7.2。

$command = 'php Cron.php send_email "'. $id .'"';
if ( substr(php_uname(), 0, 7) == "Windows" )
{
    //windows
    pclose(popen("start /B " . $command . " 1> temp/update_log 2>&1 &", "r"));
}
else
{
    //linux
    shell_exec( $command . " > /dev/null 2>&1 &" );
}

这对我来说非常有效。

我希望它对Windows有帮助。干杯。


1

“执行nohup setid your_command”

即使启动的进程可能先终止,nohup仍允许your_command继续。如果是这样,则将SIGNUP信号发送到your_command使其终止(除非它捕获到该信号并忽略它)。


根据此答案,孩子必须注册SIGHUP才能通知其父母去世。但是,终端倾向于在退出时发送HUP信号。
Cees Timmerman

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.