【问题标题】:Invoking "php" command from a PHP script causing strange process behavior从 PHP 脚本调用“php”命令导致奇怪的进程行为
【发布时间】:2013-02-08 04:31:56
【问题描述】:

我刚刚将一个站点从一个主机移动到另一个主机。服务器环境非常相似(LAMP 堆栈),所有代码在传输时都可以正常工作,除了一行。我已经对其进行了一些变异以进行测试,但仍然得到非常奇怪的结果:

<?php
$out = `php ../test/test.php 123 abc`;
?>

在 SSH 中从命令行运行 php ../test/test.php 123 abc 时,它可以正常工作,正如预期的那样。当我在 SSH 中运行:php testrunner.php(上面只有“$out”行的文件)时,它也可以按预期工作。

但是一旦我从浏览器加载testrunner.php,它就会挂起。使用ps aux | grep php 监控进程,进程似乎会产生并消亡(为简洁起见截断):

myuser   12790  0.0  0.3 259016 45284  . . . 0:00 php ../test/test.php 123 abc

如果我将“$out”行修改为:

<?php
$out = `php ../test/test.php 123 abc &`;
?>

然后我使该脚本在后台运行。令人惊讶的是,几秒钟后,当我再次运行 ps aux | grep php 时,它显示了相同的内容,但使用了新的 PID。我继续运行 ps aux 并继续使用不同的 PID 看到它。这种情况会持续很长一段时间(几秒钟,甚至一分钟)。

这对我来说很奇怪,因为 test.php 只有一行来回显一些用于测试目的的文本。

在终端上工作正常。从网络调用时挂起并有其他奇怪的行为。我错过了什么吗?

(我通过将输出重定向到一个日志文件来证明,当从 Web 浏览器运行时,PHP 脚本似乎调用了 ITSELF 而不是其他脚本 test.php。当它表现得像这样时,它不会t 接收任何$argv 参数...但是当我从命令行运行它时,一切都很好!奇怪?)

更新:天啊...我只是在观察服务器进程,而 test.php 的 PHP 进程开始失控。它们增加了数百甚至数千个进程:服务器被关闭了一分钟,SSH 等等。它现在恢复了,但我无法解释发生了什么。代码中没有循环,所涉及的两个文件都非常简单,为了测试目的而隔离...

我正在与我的房东合作,因为他们回复了我的支持票,以查看这是否与环境相关或什么...什么可能导致这种情况发生,只需更改服务器环境?

【问题讨论】:

  • 我假设您已检查 shell_exec() 已启用。 test.php 的权限是什么?您是否确定 apache/webserver 用户对 text.php 具有执行权限?权限可以解释为什么它从终端运行,但不能通过网络服务器访问
  • shell_exec() 已启用,是的。我已经尝试在 test.php(我认为是 644?)以及 755、777 以及介于两者之间的几乎所有内容(包括chmod +x test.php)上保留权限。我没有对服务器的 root 访问权限,我的主机基本上说“这应该可以工作”......希望澄清一下。
  • 这听起来可能有点迂腐,但是您检查过当前工作目录getcwd() 吗?您确定要执行的脚本在您认为的位置并且可以访问吗?无论如何,最好完全避开相对路径。此外,test.php 是可执行的可能还不够……调用进程可能还需要对其父目录的执行权限。只是抛出一些可能性......
  • 是的。我尝试了相对路径和远程路径,验证文件是否存在。 (不过要提醒一下……你知道我有多少次把头撞在墙上,然后才记得简单地重新启动 httpd??)
  • 这里是在黑暗中拍摄的,但是鉴于您在不同的环境中,这可能是您的 PHP 可执行文件路径的问题吗?你那里有shebang吗? (#!/usr/bin/php 等)?我不知道这是否可行,但是您是否尝试过$out = `/usr/bin/php /abs/path/test/test.php 123 abc`;(将正确的路径替换为 php 可执行文件和您的文件)?

标签: php process command-line-interface


【解决方案1】:

我的主人 A Small Orange 提供了帮助,但最后,我或他们所能想到的只是(来自我的支持票):

...SuPHP 或我们作为堆栈的一部分运行的其他一些基于安全的软件正在阻止您的进程生成新进程(因为这种行为可能由于显而易见的原因不安全)...

无论如何,这些脚本在我的 Macbook(与 nginx 的配置非常不同)和我的旧主机的 LAMP 堆栈上运行良好,ASO 具有类似的设置。

也许我会询问如何在不调用命令行的情况下生成长时间运行的进程,以便调用脚本不会在另一个问题中被阻塞。

【讨论】:

    【解决方案2】:

    去掉空格并加上下划线

    $out = `php ../test/test.php_123_abc`;
    

    【讨论】:

    • 你应该阅读backtick operator
    • @BenD 格式消除了他的反引号。但这并不是说其余的都是正确的。
    • @Cthulhu,是的,我知道(我以前也遇到过),但答案基本上是胡言乱语,表明对反引号的作用存在误解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多