我在 php 脚本从 cron 开始运行到超时后注意到了这个问题,但是当它从命令行手动运行时这不是问题。 (对于 CLI,PHP 默认的 max_execution_time 是 0)
所以我尝试运行一个简单的 cron:
50 8 * * * php -q /tmp/phpinfo.php > /tmp/phpinfo
脚本只会调用 phpinfo()。
令人惊讶的是,它以 html 格式写出了 phpinfo,这表明它不是作为 CLI 运行的。输出中的 max_execution_time 为 30。
从命令行手动运行脚本
php -q /tmp/phpinfo.php | less
以文本格式写出 php 信息,输出中的 max_execution_time 为 0。
我知道某处一定存在配置问题,但我就是找不到问题出在哪里。这是在我完全控制的生产服务器上发生的。在我的开发机器上从 cron 运行相同的脚本运行良好。
这里总结一下区别
function | CLI | cron |
php_sapi_name | cli | cgi-fcgi |
php_ini_loaded_file | /usr/local/lib/php.ini | /usr/local/lib/php.ini |
最佳答案
我怀疑您的问题在于缺少环境变量,特别是最重要的 $PATH
。当你运行它时:
php -q /tmp/phpinfo.php
系统必须计算出您所说的 php
是什么程序。它通过按顺序查看当前 $PATH
环境变量中的目录来执行此操作。
从普通 shell 执行,您的环境设置为它可以找到 PHP 的 CLI 版本,正如您所期望的那样。
但是,当 cron
执行一个命令时,它没有使用您的交互式 shell 设置的所有环境变量。由于您的系统上可能会有其他名为 php
的可执行文件,对于不同的“SAPI”,它可能会选择“错误”的 - 在您的情况下,cgi-fcgi
可执行文件,根据您从 php_sapi_name()
报告的输出。
要解决这个问题,首先要在普通 shell 中找到正确的 php
可执行文件的路径,方法是键入以下内容:
which php
这应该给你一个类似于 /usr/bin/php
的路径。您可以进一步检查这是否实际上是指向不同文件名的“符号链接(symbolic link)”:
ls -l $(which php)
(如果是,您会在输出中看到一个箭头,例如 /usr/bin/php ->/usr/bin/php5-cli
)
然后获取 PHP 可执行文件的完整路径并在您的 crontab 条目中使用它,因此它看起来像这样:
50 8 * * * /usr/bin/php5-cli -q /tmp/phpinfo.php > /tmp/phpinfo
关于php - 从 cron 运行 php 没有作为 CLI 运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19916949/