在proc_open之后获取真正的退出代码

时间:2011-10-04 09:02:55

标签: php process pipe exit-code

我在php中使用proc_open 启动子流程并来回发送数据。

在某些时候,我想等待流程结束并检索退出代码

问题是如果进程已经完成,我对proc_close的调用将返回-1。关于proc_close实际返回的内容显然存在很多混淆,我还没有找到一种方法来可靠地确定使用proc_open打开的流程的退出代码。

我尝试过使用proc_get_status,但是当进程已经退出时,它似乎也会返回-1。


更新

我无法让proc_get_status 给我一个有效的退出代码,无论它是如何或何时被调用的。它完全坏了吗?。

2 个答案:

答案 0 :(得分:10)

我的理解是proc_close永远不会给你一个合法的退出代码。

您只能在过程结束后获取第一次运行proc_get_status 的合法退出代码。这是一个我stole关闭php.net用户贡献笔记的流程类。您的问题的答案在is_running()方法中:

<?php
class process {

    public $cmd = '';
    private $descriptors = array(
            0 => array('pipe', 'r'),
            1 => array('pipe', 'w'),
            2 => array('pipe', 'w')
        );
    public $pipes = NULL;
    public $desc = '';
    private $strt_tm = 0;
    public $resource = NULL;
    private $exitcode = NULL;

    function __construct($cmd = '', $desc = '')
    {
        $this->cmd = $cmd;
        $this->desc = $desc;

        $this->resource = proc_open($this->cmd, $this->descriptors, $this->pipes, NULL, $_ENV);

        $this->strt_tm = microtime(TRUE);
    }

    public function is_running()
    {
        $status = proc_get_status($this->resource);

        /**
         * proc_get_status will only pull valid exitcode one
         * time after process has ended, so cache the exitcode
         * if the process is finished and $exitcode is uninitialized
         */
        if ($status['running'] === FALSE && $this->exitcode === NULL)
            $this->exitcode = $status['exitcode'];

        return $status['running'];
    }

    public function get_exitcode()
    {
        return $this->exitcode;
    }

    public function get_elapsed()
    {
        return microtime(TRUE) - $this->strt_tm;
    }
}

希望这有帮助。

答案 1 :(得分:2)

我试图通过proc_get_status获取返回代码也得到了意想不到的结果,直到我意识到我收到了我执行的最后一个命令的返回码(我将一系列命令传递给{{1 },用;分隔。)。

一旦我将命令分解为单个proc_open调用,我使用以下循环来获取正确的返回代码。请注意,通常代码执行proc_open两次,并在第二次执行时返回正确的返回代码。此外,如果进程永远不会终止,下面的代码可能会很危险。我只是以它为例:

proc_get_status