【问题标题】:PHP: non blocking shell_exec WITH command outputPHP:非阻塞 shell_exec WITH 命令输出
【发布时间】:2017-01-10 06:10:43
【问题描述】:

我正在使用 php 的 shell_exec 来调用 bash 文件、系统程序和 Ksh 文件。

shell_exec 的一个问题是,如果您需要输出,您的 Web 服务器将锁定(即不会提供新请求),直到该过程完成。一个常见的技巧是将进程设置为在后台运行 (> /dev/null 2> /dev/null &),但这当然会丢弃任何输出。

我尝试从 apache 切换到 nginx,认为这可以解决我的问题,但根本问题似乎是 php 的 shell_exec 如何阻止 i/o。即使使用 nginx,shell_exec 也会完全阻止任何新的 http 请求完成。

有谁知道如何在不锁定服务器的情况下使用 php 进行系统调用,同时还捕获输出?

我正在考虑创建一个管理异步系统调用的库,以便以后可以使用 Ajax 检索输出。

但我不想走那条路。有什么建议吗?

【问题讨论】:

    标签: php linux apache bash nginx


    【解决方案1】:

    这是常见的会话问题。

    默认情况下,当会话开始时,php 会锁定会话文件,直到会话关闭。所有其他请求都等待解锁会话文件才能继续。

    尝试将session_write_close 放在shell_exec 之前

    【讨论】:

    • session_write_close() 可以解决问题。我希望这在未来不会变得太混乱(即关闭会话然后尝试更新会话)。
    • @AvindraGoolcharan,您可以重新开始会话。您也可以更改会话处理程序。
    • 启动会话完美。今天刚体验过。
    【解决方案2】:

    如果您希望您的 PHP 脚本在外部程序运行时继续执行,您可以使用proc_open()

    如果您希望您的 PHP 脚本不阻止其他请求,您必须确保您的 PHP 脚本没有任何会阻止其他请求被服务的锁。最常见的是会话锁定,您可以按照 sectus 的建议使用 session_write_close()

    【讨论】:

      【解决方案3】:

      如何在后台运行它,但将输出重定向到文件?
      您可以使用>>| tee

      【讨论】:

      • 是的,可以。但是对于我的特殊情况,我的会话被阻止了,因为我没有打电话给session_write_close()。与shell_exec无关,@sectus 只是幸运的猜测
      【解决方案4】:

      这里可能有点远,但是创建一个新线程怎么样? http://php.net/manual/en/class.thread.php。对 php 和 linux 没有太多经验,但此类问题的一般解决方案是多线程处理您的 Web 应用程序

      【讨论】:

        【解决方案5】:

        尝试将您的 shell 执行放在带有 typescript 的屏幕会话中,即

        shell_exec("screen -dmS scriptname /bin/bash -c /path/to/script | typescript");
        

        那么当你想读取输出时:

        shell_exec("sed -e 's/$/<br>/' typescript; rm typescript");
        

        不完全确定这是否是您想要的,但我希望它有所帮助!

        编辑:在 sed 表达式中忘记了 / :P

        【讨论】:

          猜你喜欢
          • 2010-11-19
          • 1970-01-01
          • 2013-12-13
          • 1970-01-01
          • 2016-07-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多