如何获取 proc_open() 的输出

发布于 2024-11-07 18:57:07 字数 462 浏览 4 评论 0原文

我尝试从 php 中的 proc_open 方法获取输出,但是,当我打印它时,我得到了空。

$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("file", "files/temp/error-output.txt", "a")
);

$process = proc_open("time ./a  a.out", $descriptorspec, $pipes, $cwd);

据我所知,我可以使用 stream_get_contents() 获得输出,

echo stream_get_contents($pipes[1]);
fclose($pipes[1]);

但我不能这样做.. 有什么建议吗?

谢谢之前...

I've tried to get output from proc_open method in php, but, when I print it, I got empty.

$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("file", "files/temp/error-output.txt", "a")
);

$process = proc_open("time ./a  a.out", $descriptorspec, $pipes, $cwd);

as long as I know, I can get the output with stream_get_contents()

echo stream_get_contents($pipes[1]);
fclose($pipes[1]);

But I can't do that..
any suggestion?

Thx before...

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

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

发布评论

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

评论(3

迷途知返 2024-11-14 18:57:07

你的代码或多或少对我有用。 time 将其输出打印到 stderr,因此如果您要查找该输出,请查看文件 files/temp/error-output.txtstdout 管道 $pipes[1] 将仅包含程序 ./a 的输出。

我的重现:

[edan@edan tmp]$ cat proc.php 

<?php

$cwd='/tmp';
$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("file", "/tmp/error-output.txt", "a") );

$process = proc_open("time ./a a.out", $descriptorspec, $pipes, $cwd);

echo stream_get_contents($pipes[1]);
fclose($pipes[1]);

?>

[edan@edan tmp]$ php proc.php 

a.out here.

[edan@edan tmp]$ cat /tmp/error-output.txt

real    0m0.001s
user    0m0.000s
sys     0m0.002s

Your code more or less works for me. time prints its output to stderr so if you're looking for that output, look in your file files/temp/error-output.txt. The stdout pipe $pipes[1] will only contain the output of the program ./a.

My repro:

[edan@edan tmp]$ cat proc.php 

<?php

$cwd='/tmp';
$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("file", "/tmp/error-output.txt", "a") );

$process = proc_open("time ./a a.out", $descriptorspec, $pipes, $cwd);

echo stream_get_contents($pipes[1]);
fclose($pipes[1]);

?>

[edan@edan tmp]$ php proc.php 

a.out here.

[edan@edan tmp]$ cat /tmp/error-output.txt

real    0m0.001s
user    0m0.000s
sys     0m0.002s
晨光如昨 2024-11-14 18:57:07

这是 proc_open() 的另一个示例。
我在本例中使用 Win32 ping.exe 命令。 CMIIW

set_time_limit(1800);
ob_implicit_flush(true);

$exe_command = 'C:\\Windows\\System32\\ping.exe -t google.com';

$descriptorspec = array(
    0 => array("pipe", "r"),  // stdin
    1 => array("pipe", "w"),  // stdout -> we use this
    2 => array("pipe", "w")   // stderr 
);

$process = proc_open($exe_command, $descriptorspec, $pipes);

if (is_resource($process))
{

    while( ! feof($pipes[1]))
    {
        $return_message = fgets($pipes[1], 1024);
        if (strlen($return_message) == 0) break;

        echo $return_message.'<br />';
        ob_flush();
        flush();
    }
}

希望这有帮助 =)

this is another example with proc_open().
I am using Win32 ping.exe command in this example. CMIIW

set_time_limit(1800);
ob_implicit_flush(true);

$exe_command = 'C:\\Windows\\System32\\ping.exe -t google.com';

$descriptorspec = array(
    0 => array("pipe", "r"),  // stdin
    1 => array("pipe", "w"),  // stdout -> we use this
    2 => array("pipe", "w")   // stderr 
);

$process = proc_open($exe_command, $descriptorspec, $pipes);

if (is_resource($process))
{

    while( ! feof($pipes[1]))
    {
        $return_message = fgets($pipes[1], 1024);
        if (strlen($return_message) == 0) break;

        echo $return_message.'<br />';
        ob_flush();
        flush();
    }
}

Hope this helps =)

咋地 2024-11-14 18:57:07

这是读取 stdout 和 stderr 的完整函数。

/**
 * Executes process
 *
 * @param string $command
 * @param string $cwd
 * @param bool $exitOnError
 * @return void
 */
function exec(string $command, string $cwd, bool $exitOnError = true): void
{
    $descriptorSpec = array(
        0 => array('pipe', 'r'), // stdin is a pipe that the child will read from
        1 => array('pipe', 'w'), // stdout is a pipe that the child will write to
        2 => array("pipe", "w"), // stderr is a pipe that the child will write to
    );

    $process = proc_open($command, $descriptorSpec, $pipes, $cwd);

    if (is_resource($process)) {
        do {
            $read = array($pipes[1], $pipes[2]);
            $write = null;
            $except = null;

            $status = proc_get_status($process);
            if ($status['running'] === false) {
                break;
            }

            if (stream_select($read, $write, $except, 5)) {
                foreach ($read as $c) {
                    if (feof($c) || fstat($c)['size'] === 0) {
                        continue;
                    }
                    $read = fread($c, 1024);

                    if ($read === false) {
                        continue;
                    }

                    echo $read;
                }
            }
        } while (!feof($pipes[1]) | !feof($pipes[2]));

        fclose($pipes[0]);
        fclose($pipes[1]);
        fclose($pipes[2]);

        // It is important to close any pipes before calling
        // proc_close to avoid a deadlock
        $returnValue = proc_close($process);

        if ($returnValue != 0) {
            if ($exitOnError) {
                exit(1);
            }
        }

    } else {
        echo "Couldn't open $command";
        if ($exitOnError) {
            exit(1);
        }
    }
}

Here is a complete functions which reads stdout and stderr.

/**
 * Executes process
 *
 * @param string $command
 * @param string $cwd
 * @param bool $exitOnError
 * @return void
 */
function exec(string $command, string $cwd, bool $exitOnError = true): void
{
    $descriptorSpec = array(
        0 => array('pipe', 'r'), // stdin is a pipe that the child will read from
        1 => array('pipe', 'w'), // stdout is a pipe that the child will write to
        2 => array("pipe", "w"), // stderr is a pipe that the child will write to
    );

    $process = proc_open($command, $descriptorSpec, $pipes, $cwd);

    if (is_resource($process)) {
        do {
            $read = array($pipes[1], $pipes[2]);
            $write = null;
            $except = null;

            $status = proc_get_status($process);
            if ($status['running'] === false) {
                break;
            }

            if (stream_select($read, $write, $except, 5)) {
                foreach ($read as $c) {
                    if (feof($c) || fstat($c)['size'] === 0) {
                        continue;
                    }
                    $read = fread($c, 1024);

                    if ($read === false) {
                        continue;
                    }

                    echo $read;
                }
            }
        } while (!feof($pipes[1]) | !feof($pipes[2]));

        fclose($pipes[0]);
        fclose($pipes[1]);
        fclose($pipes[2]);

        // It is important to close any pipes before calling
        // proc_close to avoid a deadlock
        $returnValue = proc_close($process);

        if ($returnValue != 0) {
            if ($exitOnError) {
                exit(1);
            }
        }

    } else {
        echo "Couldn't open $command";
        if ($exitOnError) {
            exit(1);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文