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

发布于 2024-12-08 03:32:49 字数 440 浏览 0 评论 0原文

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

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

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

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


更新

我无法获取 proc_get_status给我一个有效的退出代码,无论如何或何时调用它。是不是彻底坏掉了?

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 call 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?.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我喜欢麦丽素 2024-12-15 03:32:49

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

您只能在进程结束后第一次运行proc_get_status时获取合法的退出代码。这是我从 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;
    }
}

希望这会有所帮助。

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.

旧城烟雨 2024-12-15 03:32:49

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

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

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

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文