【问题标题】:PHP system() - return status is always 0PHP system() - 返回状态始终为 0
【发布时间】:2011-05-07 02:57:06
【问题描述】:

我需要运行以下脚本。

// File: script_a.php
<?php exit(1); ?>

// File: script_b.php
<?php 
     system('php script_a.php', $return);
     var_dump($return);
?>

现在我的问题是:在运行script_b.php 的Windows 系统上,如预期的那样显示int(1)。在我们的 Unix-Server 上,我总是得到 int(0),这让我无法检查是否在 script_a.php 内部发生了某种故障。

有谁知道这个问题以及如何解决它?

【问题讨论】:

  • 从命令行运行 script_a.php 时$? 包含什么?
  • 你在unix服务器上使用的是什么php版本,与windows比较
  • 如果我从命令行运行 script_b,一切正常。 $是什么?
  • windows系统运行PHP 5.2.6,Unix运行5.2.11
  • $? 是 bash 中的返回参数。 php script_a.php ; echo $?

标签: php unix system return status


【解决方案1】:

我知道这是一个旧线程,但我遇到了类似的问题。

当我让脚本在后台运行时,退出状态被设置为 0,类似于

system('php script_a.php &', $return);

您是否可以一直这样做,但只是为了可读性而进行概括?

【讨论】:

    【解决方案2】:

    考虑到您的评论,当您的 script_b 类似于

    时,您的问题出现在 UNIX 系统中

    system('php script_a.php | tee myLogFile', $return);

    你可以使用这个语法

    system("bash -c 'php script_a.php | tee log.txt ; exit \${PIPESTATUS[0]}'", $return);

    执行 man bash 并搜索 PIPESTATUS 以了解更多详细信息。

    【讨论】:

      【解决方案3】:

      不确定这些问题是否相关,但您可以查看exec always returns -1 (or 127),因为我过去遇到过类似的问题......即使我没有真正解决它。

      在您的情况下,这可能是另一个问题,不确定它是如何重现的,但我见过一些情况,其中未知命令的返回字符串将是来自bash (bash: command not found) 的返回字符串。在大多数服务器上,我什么都没有。您可以尝试检查当前用户的 shell 设置(我假设它是 www-data)

      【讨论】:

        【解决方案4】:

        您需要以root身份运行或使用sudo通过php访问。

        试试这样的:-

        system('sudo /usr/bin/php -f script_a.php', $return);
        

        在你的 script_b.php 中

        并编辑 /etc/sudoers 以添加以下行:-

        apache    ALL=(ALL) NOPASSWD: /usr/bin/php -f script_a.php
        

        如果 php 不在 /usr/bin/php 中,请更改该引用 并提及 script_a.php 文件的完整路径,例如 /var/www/html/script_a.php 或它的物理位置。

        谢谢。

        【讨论】:

        【解决方案5】:

        试试:

        <?php
            die(1);
        ?>
        

        如果也失败了,请查看以下的标准输出:

        strace php script_a.php
        

        【讨论】:

          【解决方案6】:

          我无法在我的系统上重现这个,Ubuntu Hardy。这是一个示例:

          /tmp$ mkdir /tmp/sbuzz
          /tmp$ cd /tmp/sbuzz
          /tmp/sbuzz$ echo '<?php exit(1); ?>' >script_a.php  
          /tmp/sbuzz$ cat >script_b.php
          <?php 
               system('php script_a.php', $return);
               var_dump($return);
          ?>
          /tmp/sbuzz$ php script_b.php 
          int(1)
          /tmp/sbuzz$ echo '<?php exit(2); ?>' >script_a.php  
          /tmp/sbuzz$ php script_b.php
          int(2)
          /tmp/sbuzz$ 
          

          退出代码 0 表示程序成功执行,所以听起来您可能运行了错误的 script_a.php 或者“php”可执行文件没有按照您的预期执行?也许您在解释器之前的路径中有一个名为“php”的脚本? “哪个php”报告了什么?在我的系统上显示“/usr/bin/php”。

          如果 PHP 找不到脚本,它会以 1 退出,例如:

          /tmp/sbuzz$ cat script_b.php 
          <?php
               system('php doesnt_exist_script_a.php', $return);
               var_dump($return);
          ?>
          /tmp/sbuzz$ php script_b.php 
          Could not open input file: doesnt_exist_script_a.php
          int(1)
          /tmp/sbuzz$
          

          在这种情况下,我更改了 script_b.php 以尝试运行一个不存在的脚本,并且我得到了退出代码 1(如果它成功完成应该是 2,因为我更改了上面的 script_a),但是它还显示了无法运行程序的错误。

          您可能想尝试将其更改为专门运行 PHP 可执行文件的完整路径:

          system('/usr/bin/php script_a.php')
          

          或者还有脚本的完整路径:

          system('/usr/bin/php /tmp/sbuzz/script_a.php')
          

          您也可以尝试专门执行一个返回 1 的程序,就像另一个数据点一样,例如:

          system('false')
          system('bash -c "exit 69"')
          

          您可能想尝试 1 以外的退出代码,这是常见的失败。这就是为什么我在上面做了“69 号出口”。 "false" 将以 1 退出。

          当然也可以尝试直接运行script_a.php:

          /tmp/sbuzz$ php script_a.php 
          /tmp/sbuzz$ echo $?
          2
          /tmp/sbuzz$ 
          

          “$?”是最后一个运行命令的退出代码,在 shell 提示符下。

          【讨论】:

            【解决方案7】:

            我也无法重现它(PHP 5.3.3,Ubuntu)。

            当我将退出值设置为更好的 grep 值时,例如“666”,跟踪脚本也返回了预期的结果:

            strace -f php5 script_b.php 2>&1 | grep EXITSTATUS
            
            [pid 18574] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0, NULL) = 18575
            waitpid(18574, [{WIFEXITED(s) && WEXITSTATUS(s) == 666}], 0) = 18574
            

            当你使用系统调用时,strace 的“-f”让它跟随子进程。 "2>&1" 将 stderr 重定向到 stdout 以让所有内容都 grep。您也可以将其通过管道传递给“|less”以通过,但输出很长且可读性不强。

            【讨论】:

              【解决方案8】:

              尝试使用 PHP 可执行文件和脚本文件名的绝对路径进行 PHP system 调用,例如:system('/usr/bin/php /path/to/script_a.php', $return);。可能是路径问题。 (您可以通过 which php 找到 PHP 可执行文件的绝对路径。

              另外,正如有人建议的那样,尝试通过在命令行上运行 php script_a.php; echo $? 来调试 UNIX 服务器上 script_a.php 的实际返回值。那echo会输出最后一个返回值,即script_a.php返回的值。

              无论如何,我建议使用return 语句执行include,如include() documentation 的示例#5 中所述。如果您可以像这样调整您的脚本,这是一种更有效的交流方式。

              // File: script_a.php
              <?php return 1; ?>
              
              // File: script_b.php
              <?php 
                   $return = (include 'script_a.php');
                   var_dump($return);
              ?>
              

              【讨论】:

                【解决方案9】:

                __halt_compiler() 在某处被调用,可以检查吗?

                【讨论】:

                • @Ignacio - 我可以在嵌入 __halt_compiler(); exit(1); 时复制相同的输出,并且可能将 unix 别名中的 PHP 复制到某些东西?
                • 在这种情况下不会在两个平台上都失败吗?
                • 是的,这两种情况都必须失败,但所有者只说 php script_a.php ,而 php 可能会有所不同
                【解决方案10】:

                您可能想检查它是否在 Unix 机器上调用了正确的 php 可执行文件。在许多 UNIX 系统上,您需要调用 php 的 php-cli 可执行文件,以便在命令行上使用。 要检查的另一件事是权限。可能执行 script_b.php 脚本的用户没有执行 script_a 的权限?

                【讨论】:

                  【解决方案11】:

                  您是否检查过 unix 服务器上是否启用了安全模式?

                  PHP 注释:

                  注意:启用安全模式后,您 只能执行里面的文件 安全模式执行目录。为了实用 原因,目前不允许 在路径中有 .. 组件 可执行文件。

                  或者系统功能被禁止执行?

                  【讨论】:

                  • 安全模式已关闭。并且允许调用系统。如果我在退出前在 script_a 中加入一些 echo 语句,我通常可以获取该输出,但退出状态仍然为 0。
                  • 你试过其他的执行方法吗?也许 exec() 或 passthru() 工作正常
                  • 我都试过了,exec() 和 passthru()。在命令行上,结果符合预期,但在网络服务器上执行导致 $return 为 0。
                  • 如果你使用 echo 1 而不是 exit(1) 怎么办?带有数字的退出只是发送一个退出信号,并且不会根据 php 文档打印任何内容,也许这就是问题所在。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-01-20
                  • 2021-11-05
                  • 2018-12-10
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多