Shell命令适用于命令行,但不适用于PHP exec

时间:2010-08-11 16:33:43

标签: php shell command-line

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

  

最长执行时间为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,这证明了我的想法,我真的不明白为什么这个脚本在最大执行时间失败了!

7 个答案:

答案 0 :(得分:1)

您的脚本似乎需要花费太多时间才能执行,尝试

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

您可以通过在脚本顶部包含此内容来临时设置超时。如果在使用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.

答案 3 :(得分:1)

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

明确键入/usr/bin/php(根据需要修改)会有什么不同吗?

答案 4 :(得分:1)

我实际上发现了问题(有点)。当错误实际上在max_execution_time as described here

时,似乎可能是PHP报告max_input_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但是

答案 5 :(得分:0)

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

答案 6 :(得分:0)

创建如下的

包装器.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

中为我工作
相关问题