【问题标题】:Shell command works on command line but not in PHP execShell 命令适用于命令行,但不适用于 PHP exec
【发布时间】:2011-03-28 12:00:51
【问题描述】:

我有一个命令,当直接在命令行上运行时,它可以按预期工作。它运行超过 30 秒并且不会抛出任何错误。当通过 php 函数 exec()(包含在由 cron 调用的脚本中)通过 PHP 脚本调用相同的命令时,它会引发以下错误:

最长执行时间 30 秒 超过

我们有许多服务器,我已经在一个非常相似的服务器上运行了这个命令,该服务器具有完全相同的数据集,没有任何问题,所以我很高兴没有脚本级别的问题。我越来越倾向于认为这与服务器级别的某些东西有关——无论是在 PHP 设置中还是在某种方式的服务器设置中,但真的不知道在哪里看。对于那些感兴趣的人来说,两个服务器的最大执行时间都是 30 秒。

命令本身是这样调用的 -

从命令行为:

root@server>php -q /path/to/file.php

这行得通...

并通过 PHP 文件中的 cron 作为:

exec("php -q /path/to/file.php");

这会引发最大执行时间错误。我一直认为从命令行运行 PHP 时没有执行时间限制。

我应该指出,被调用的脚本调用了许多其他脚本,而出错的正是这些脚本之一。查看我的日志,最大执行时间错误实际上也发生在 30 秒之前!因此,在被调用后不到 30 秒,一个由 cron 脚本调用的脚本(该脚本似乎在 CLI 中运行)引发了最大执行错误。

为了检查脚本是否按预期运行(作为没有最大执行时间的 CLI),我执行了以下检查:

包含此代码的 PHP 脚本:

// test.php
echo exec("php test2.php");

test2.php 包含的位置:

echo ini_get('max_execution_time');

这个脚本是这样运行的:

root@server> php test.php
// returns 0

这证明以这种方式调用的脚本在 CLI 下运行,最大执行时间为 0,这正好证明了我的想法,我真的不明白为什么这个脚本在最大执行时间上失败了!

【问题讨论】:

  • 如果从命令行而不是 cron 运行 PHP 脚本会发生什么?
  • 您说“在命令行上直接运行时工作正常”,但这还不够信息:尽管在 shell 提示符下工作正常,但 PHP 的 max/exec 是否需要 30 秒/time 设置(忘记确切名称)显然设置为?
  • @George - 我曾假设通过 exec() 运行脚本等同于在 CLI 下运行它 - 不是这样吗?
  • 我降低了这个问题,因为尽管多次被问到从命令行执行脚本需要多长时间,但由于某种原因他拒绝回答。
  • @George - 有点苛刻,因为我已经 afk,我没有拒绝回答任何事情!从命令行运行脚本需要 30 多秒,但它并不像被调用的脚本调用脚本那样简单,该脚本又调用许多其他脚本,并且被调用的脚本抛出错误

标签: php shell command-line


【解决方案1】:

看来你的脚本执行时间太长了,试试

设置时间限制,http://php.net/manual/en/function.set-time-limit.php

或查看此帖子: Asynchronous shell exec in PHP

【讨论】:

    【解决方案2】:

    该命令在命令行上是否需要超过 30 秒?您是否尝试过在 php.ini 中增加执行超时?

    【讨论】:

      【解决方案3】:

      您可以通过将其包含在脚本顶部来临时设置超时。在安全模式下运行时,这将不起作用,如将max_execution_time 设置为ini_set() 的文档中指定的那样。

      <?php
          ini_set('max_execution_time', 60);  // Set to be longer than 
                                              // 60 seconds if needed
      
          // Rest of script...
      ?>
      

      文档中需要注意的一点是:

      从命令行运行 PHP 时 默认设置为 0。

      【讨论】:

      • 我曾假设使用 exec 运行脚本等同于在 CLI 下运行它。也许不是这样?
      • 如果是这样,那么由 cron 调用的 PHP 脚本(因此使用 CLI)调用 PHP 脚本使用 exec() 应该没有最大执行时间?
      • @snaken - 这正是我的想法
      【解决方案4】:

      php -v | grep cli,从 shell 和 cron 加载的 php 文件的 exec 命令中运行显示什么?

      明确输入/usr/bin/php(酌情修改)有什么不同吗?

      【讨论】:

      • 添加 /usr/bin/php 得到相同的结果
      • 这很奇怪——你在 cron 运行的 PHP 文件中尝试了exec('php -v | grep cli');?我同意它不应该超时。该服务器是否有例如应用了 Suhosin 补丁? php 和 php-cli 有单独的 php.inis 吗?
      • 根据管理员的说法,我们有一个主要的 php.ini 并且没有 suhosin 补丁
      • 然后被难住了:抱歉 :-)。我倾向于怀疑您的 php-cli 版本中存在错误。 php -d max_execution_time=0 -q /path/to/file.php 有效吗?
      • 好的,试过了 - 现在得到“超过 0 秒的最大执行时间”!
      【解决方案5】:

      我实际上已经找到了问题所在(有点)。当错误实际上是max_input_time as described here 时,似乎它可能是 PHP 报告 max_execution_time 的错误

      我尝试将 exec 调用更改为 php -d max_execution_time=0 -q /path/to/file.php,但出现错误“超过 0 秒的最大执行时间”,这没有任何意义,我将代码更改为 php -d max_input_time=0 -q /path/to/file.php,并且代码运行时没有出错。不幸的是,它仍然在 10 分钟后运行。至少这证明问题出在max_input_time 上

      【讨论】:

        【解决方案6】:

        我很惊讶上面没有人真正为 completed exec 调用计时。问题是 exec(x) 比命令行 x 花费的时间要长得多。我有一个非常复杂的 perl 脚本(具有 8 级内部递归),从命令行执行大约需要 40 秒。在 php 脚本中使用 exec 来调用相同的 perl 程序需要大约 300 秒的时间来执行,即大约 7 倍的时间。这是一个出乎意料的效果,以至于人们没有将最大执行时间增加到足以看到他们的程序完成的程度。结果,他们对超时感到困惑。 (顺便说一句,我在一台标称 8 cpu 的快速机器上运行 WAMP,而我的 php 程序的其余部分基本上是微不足道的,所以时间差必须完全在 exec 中。)

        【讨论】:

          【解决方案7】:

          如下创建 wrapper.sh 文件

          export DISPLAY=:0<br>
          xhost + 2>>/var/www/err.log<br>
          /usr/bin/php "/var/www/read_sms1.php" 2>>/var/www/err.log<br>
          

          并将其放入 cron 中,如下所示

           bash  /var/www/wrapper.sh<br>
          y read_sms1.php  contain<br>
          $ping_ex = exec("/usr/local/bin/gnokii --getsms SM 1 end  ", $exec_result, $pr);  
          

          以上解决方案在ubuntu 12.04中对我来说效果很好

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-07-06
            • 2015-02-24
            • 2021-01-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-17
            相关资源
            最近更新 更多