【问题标题】:php exec command (or similar) to not wait for resultphp exec 命令(或类似命令)不等待结果
【发布时间】:2011-04-18 16:15:38
【问题描述】:

我有一个要运行的命令,但我不想让 PHP 坐等结果。

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

是否有可能让 PHP 不等待结果.. 即直接启动它并继续执行下一个命令。

我找不到任何东西,甚至不确定它是否可能。我能找到的最好的结果就是有人在马上开始做 CRON 工作。

【问题讨论】:

标签: php exec


【解决方案1】:

来自documentation

为了执行一个命令并且让它不挂起你的 PHP 脚本而
它运行,你运行的程序一定不能输出回PHP。为此,
将 stdout 和 stderr 都重定向到 /dev/null,然后将其作为背景。

&gt; /dev/null 2&gt;&amp;1 &amp;

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

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

【讨论】:

  • 非常感谢!有很多“解决方案”实际上不起作用(主浏览器线程仍在等待)。许多解决方案只在末尾讲述“&”,这还不够。也就是说,对我来说,一个更简单的解决方案是: exec('nohup your_command > /dev/null 2>&1 &') 就足够了。
  • 为什么你不需要将stdin 也移植到/dev/null?链接到 shell 的进程输入是否足以阻止 nohup “放弃”子进程? (他们在这个答案中确实改变了stdinsuperuser.com/questions/178587/…
  • 另外,你为什么同时调用nohupsetsid?我找不到太多关于哪个更好或它们有何不同的信息.. (stackoverflow.com/questions/10247721/…)
  • @Christin:您的解决方案适用于我的问题:stackoverflow.com/questions/25700904/… 您能回答这个问题吗?然后我可以用绿色的答案结束这个问题。
  • @Christin :你能看看我的问题吗,它似乎和我的问题一样:stackoverflow.com/questions/35331958/…
【解决方案2】:

您可以在后台运行该命令,方法是在其末尾添加&amp;

exec('run_baby_run &');

但是单独这样做会挂起你的脚本,因为:

如果一个程序以 exec 函数启动,为了让它继续在后台运行,程序的输出必须重定向到一个文件或另一个输出流。否则会导致 PHP 挂起,直到程序执行结束。

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

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

【讨论】:

  • 不重定向标准错误,并被崩溃的网络服务器杀死。
【解决方案3】:

这使用 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);

【讨论】:

  • 我认为您在 2&gt;&amp;1echo 之间缺少一个 &amp; 符号,对吗?
  • 如果父母被杀,nohup 是否也让孩子继续运行?
  • @santiagoarizti 是的,我修复了它,因为代码无法正常工作
【解决方案4】:

我知道这个问题已经得到解答,但我在这里找到的答案不适用于我的场景(或 Windows)。

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

$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 的人。干杯。

【讨论】:

  • 谢谢,正是我需要的。
  • 系统找不到指定的路径。我认为 temp/update_log 不清楚。你能解释一下吗?
  • @rahulsingh 该文件路径只是您当前工作目录中的文件,意思是,它假设您在当前目录中有一个文件夹名称temp,该文件夹中有一个名为upload_log的文件,就是这样。
【解决方案5】:

有两种可能的方式来实现它。 最简单的方法是直接结果到 dev/null

exec("run_baby_run > /dev/null 2>&1 &");

但如果您有任何其他操作要执行,您可以考虑ignore_user_abort 在这种情况下,即使您关闭连接,脚本也会运行。

【讨论】:

    【解决方案6】:

    “执行 nohup 设置你的命令”

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

    【讨论】:

    • 根据this answer,孩子必须注册 SIGHUP 才能收到父母去世的通知。不过,终端倾向于在退出时发送 HUP 信号。
    【解决方案7】:

    在 Windows 上,您可以使用 COM 对象:

    if(class_exists('COM')) {
        $shell = new COM('WScript.Shell');
        $shell->Run($cmd, 1, false);
    }
    else {
        exec('nohup ' . $cmd . ' 2>&1 &');
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-27
      • 1970-01-01
      • 2014-08-08
      • 2012-08-13
      • 2016-03-30
      • 2017-07-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多