最近,一些 PHP cron 作业在共享服务器上开始失败。近一年来,它们一直运行正常,没有出现任何错误,也无需更新,但现在却因语法错误而无法运行。到底发生了什么?
事实证明这些脚本突然在 PHP 4 而不是 PHP 5 下运行。在 /usr/local/bin/php 上安装了 PHP 4 的一个版本,但这些脚本上的“shebang”行是这样的:
#!/usr/local/php5/bin/php
我做了一些实验:
% /usr/local/php5/bin/php --version
PHP 5.2.6 (cli) (built: May 11 2008 13:09:39)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
with Zend Extension Manager v1.2.2, Copyright (c) 2003-2007, by Zend Technologies
with Zend Optimizer v3.3.3, Copyright (c) 1998-2007, by Zend Technologies
% echo '<?= phpversion() ?>' | /usr/local/php5/bin/php
5.2.6
% printf '#!/usr/local/php5/bin/php\n<?= phpversion() ?>' > version
% chmod +x version
% ./version
5.2.6
% mv version x.php
% ./x.php
4.4.9
我不知道 Linux 会让文件扩展名覆盖 shebang 行,但这就是我看到的。托管公司的支持人员不知道为什么会发生这种情况(或者最近发生了什么变化导致这种情况发生),所以我采取了一种解决方法:重命名脚本,使它们不再以“.php”结尾。
cron 作业又开始运行了,但我讨厌“别这么做”这样的回答。我真的很好奇这种行为是从哪里来的,因为我从未在 *nix 的 shell 级别看到过这样的事情。我在 zsh 和 bash 下都进行了测试,所以我认为不能怪 shell 配置。我在 /etc 下搜索了“php”,看看是否能给我一些线索,但没有。有什么想法吗?
答案1
听起来您已经使用 binfmt_misc 注册了 php。
查看该主题的手册页:binfmt_misc.txt
您需要通过向其回显 -1 来取消注册 php binfmt_misc 处理程序(必须是 root)。如果这是您的问题,它将列在 /proc/sys/fs/binfmt_misc/ 中。
需要注意的是,这可能会破坏系统上的其他内容。例如,如果正在执行另一个 PHP 脚本但没有有效的 shebang。CGI 或 suExec 可能会出现问题,具体取决于它们的配置。简而言之,一定要测试所有内容。
答案2
它看起来确实像 binfmt_misc,而且您的托管公司似乎确实有点疯狂 :) 但我怀疑他们这样做可能是为了兼容性,使 .php 文件使用 php4,而 php5 文件使用 php5。尝试使用 php5 扩展。不必对网站上的所有文件都执行此操作(只有 cronjobs 和其他作为服务器作业/脚本运行的东西),因为您的网络服务器将拥有自己的执行逻辑/处理程序。