开发者

getting the real exit code after proc_open

开发者 https://www.devze.com 2023-04-10 05:32 出处:网络
I\'m using proc_open in php to launch a subprocess and send data back and forth. At some point I\'d like to wait for the process to end and retrieve the exit code.

I'm using proc_open in php to launch a subprocess and send data back and forth.

At some point I'd like to wait for the process to end and retrieve the exit code.

The problem is that if the process has already finished, my ca开发者_StackOverflow社区ll to proc_close returns -1. There is apparently much confusion over what proc_close does actually return and I haven't found a way to reliably determine the exit code of a process opened with proc_open.

I've tried using proc_get_status, but it seems to also return -1 when the process has already exited.


Update

I can't get proc_get_status to ever give me a valid exit code, no matter how or when it is called. Is it broken completely?.


My understanding is that proc_close will never give you a legit exit code.

You can only grab the legit exit code the first time you run proc_get_status after the process has ended. Here's a process class that I stole off the php.net user contributed notes. The answer to your question is in the is_running() method:

<?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;
    }
}

Hope this helps.


I also was getting unexpected results trying to get the return code via proc_get_status, until I realized I was getting the return code of the last command I had executed (I was passing a series of commands to proc_open, separated by ;).

Once I broke the commands into individual proc_open calls, I used the following loop to get the correct return code. Note that normally the code is executing proc_get_status twice, and the correct return code is being returned on the second execution. Also, the code below could be dangerous if the process never terminates. I'm just using it as an example:

$status = proc_get_status($process);
while ($status["running"]) {
  sleep(1);
  $status = proc_get_status($process);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号