繁体   English   中英

Shell命令可在命令行上运行,但不适用于PHP exec

[英]Shell command works on command line but not in PHP exec

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

超过30秒的最大执行时间

我们有许多服务器,我已经在具有完全相同数据集的非常相似的服务器上运行了此命令,而没有任何问题,因此我很高兴没有脚本级问题。 我越来越倾向于认为这与服务器级别的某些事情有关-在PHP设置中还是在服务器设置中以某种方式,但实际上不确定在哪里查找。 对于那些感兴趣的服务器,两台服务器的最大执行时间为30秒。

命令本身就是这样的-

从命令行为:

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

这可行...

并通过cron在PHP文件中如下:

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

似乎您的脚本执行时间过多,请尝试

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

或查看这篇文章: PHP中的异步shell exec

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

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

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

    // Rest of script...
?>

文档中需要注意的一件事是:

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

php -v | grep cli是什么? php -v | grep cli ,既可以在shell中运行,又可以在cron加载的php文件中的exec命令中运行?

显式键入/usr/bin/php (适当修改)是否有区别?

我实际上已经找到了问题所在(种类)。 似乎当报告错误实际上是与max_input_time时,PHP报告了max_execution_time被超过的一个错误, 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

令我惊讶的是,以上任何人都没有真正安排完成的 exec调用的时间。 问题在于exec(x)比命令行x需要更长的时间。 我有一个非常复杂的perl脚本(具有8个级别的内部递归),大约需要40秒才能从命令行执行。 在php脚本中使用exec来调用相同的perl程序需要大约300秒的时间来执行,即,时间要长大约7倍。 这是一种意想不到的效果,以致人们没有充分增加他们的最大执行时间来完成他们的程序。 结果,它们被超时迷住了。 (顺便说一句,我在WAMP上以标称8 cpus的速度运行在一个快速的机器上,其余的php程序本质上是微不足道的,因此时间差必须完全在exec中。)

创建如下的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对我来说很好

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM