【问题标题】:Running shell_exec() in background AND getting its output afterwards在后台运行 shell_exec() 并在之后获取其输出
【发布时间】:2016-12-13 07:40:18
【问题描述】:

首先,我想指出,这与thisthis 以及其他相关问题不重复。我也在问如何获得输出,我的问题主要与此有关。

我需要从 PHP 运行一个 bash 脚本并在 PHP 中获取它的输出。但是,这样做:

echo shell_exec('script');

由于 Apache 的 FcgidIOTimeout,在第 60 秒消失。如果我使用以下在后台运行它,我将无法获得输出:

shell_exec('<myscript> > /dev/null 2>/dev/null &');

我不能:

  • 修改 bash 脚本;
  • 代码和所有功能都需要放在一个文件中(除非我使用临时文件);
  • 如果我要将shell_exec() 函数的输出写入临时文件,我还需要找到一种方法来验证是否 进程已完成;
  • 使用数据库是我无法承受的过度杀伤力;

我目前唯一的想法是使用 PHP 创建一个 tmp 文件并将输出写入其中,然后使用 top -c | grep &lt;myscript&gt;(带有刷新按钮) 如果它返回 true,那么它仍然是进行中。但是,我怀疑这在大多数情况下都不实用且高效。

重要的是我使用临时文件而不是实际创建要写入的“永久”文件。

【问题讨论】:

  • 你能用top -c | grep代替pgrep吗?你仍然有同样的问题,但this question 显示了如何检查进程是否仍在从 php 运行
  • 使用“安全”吗?在“安全”下,我的意思是它是否一直可靠。
  • pgrep 对于查找具有正确名称的进程是可靠的(比top + grep 我敢打赌),但无论它是你的同一个脚本实例,它可能是如果它具有相同的名称和 PID,但总有可能你会倒霉。
  • 我 - 应该 - 一次只运行一个实例。在我的情况下,更多的可能性很小。感谢您的提醒,稍后会尝试并告诉您是否有效。

标签: php bash shell


【解决方案1】:
  • 类似问题的解决方案:几年前我遇到过类似问题。我必须将文件上传到 FTP 服务器。我想知道如何与 FTP 服务器通信文件已完全上传,以便 FTP 服务器可以对其执行一些任务。我的解决方案是在文件完全上传后将文件重命名为 *.completed 之类的名称。然后 FTP 服务器上的进程只能查找 *.completed 文件。

  • 针对您的问题调整的解决方案:建议您在 bash 脚本生成临时文件后重命名它。这样你就可以独立判断脚本是否执行成功。 shell_exec() 可能看起来像这样:

    shell_exec('<myscript> > tmp-file && mv tmp-file tmp-file.completed &');
    

    请注意,这只会将频道 STDOUT 重定向到 tmp 文件中。如果您还想将 STDERR 重定向到 tmp 文件,请尝试以下操作:

    shell_exec('<myscript> &> tmp-file && mv tmp-file tmp-file.completed &');
    

【讨论】:

  • 这是个好主意。感谢您抽出一些时间为我写下来。我会尝试一下,如果它按预期工作,我会接受答案。
猜你喜欢
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多