PHP 读取 shell_exec 实时输出

新手上路,请多包涵

我只是在我的 Linux 服务器上试验 PHP 和 shell_exec 。这是一个非常酷的功能,到目前为止我真的很喜欢它。有没有办法查看命令运行时正在进行的实时输出?

例如,如果 ping stackoverflow.com 运行,当它 ping 目标地址时,每次 ping 时,用 PHP 显示结果?那可能吗?

我很想看到缓冲区运行时的实时更新。也许这是不可能的,但它肯定会很好。

这是我正在尝试的代码,我尝试过的每一种方式总是在命令完成后显示结果。

 <?php

  $cmd = 'ping -c 10 127.0.0.1';

  $output = shell_exec($cmd);

  echo "<pre>$output</pre>";

?>

我尝试将 echo 部分放在一个循环中,但仍然没有运气。任何人对让它在屏幕上显示实时输出而不是等到命令完成有什么建议吗?

我试过 execshell_execsystempassthru .他们每个人都在完成后显示内容。除非我使用了错误的语法或者我没有正确设置循环。

原文由 Palumbo Software 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 703
1 个回答

要读取进程的输出, popen() 是要走的路。您的脚本将与程序并行运行,您可以通过读取和写入它的输出/输入与它进行交互,就像它是一个文件一样。

但是,如果您只想将其结果直接转储给用户,您可以切入正题并使用 passthru()

 echo '<pre>';
passthru($cmd);
echo '</pre>';

如果你想在程序运行时显示输出,你可以这样做:

 while (@ ob_end_flush()); // end all output buffers if any

$proc = popen($cmd, 'r');
echo '<pre>';
while (!feof($proc))
{
    echo fread($proc, 4096);
    @ flush();
}
echo '</pre>';

此代码应运行命令并在运行时将输出直接推送给最终用户。

更多有用信息

请注意,如果您正在使用会话,那么其中一个正在运行将阻止用户加载其他页面,因为会话强制并发请求不会发生。为防止这成为问题,请在循环之前调用 session_write_close()

如果您的服务器位于 nginx 网关后面,则 nginx 缓冲可能会破坏所需的行为。设置标题 header('X-Accel-Buffering: no'); 以提示 nginx 它不应该这样做。由于首先发送标头,因此必须在脚本的开头调用它,然后再发送任何数据。

原文由 Havenard 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏