PHP stream_select()无法捕获流的状态更改

时间:2018-12-22 15:53:16

标签: php bash command-line-interface

我想创建一个运行命令行管理程序或程序并捕获stdout和stderr的PHP CLI脚本。

我无法使stream_select()工作。

为了证明这一点,我创建了一个测试脚本,该脚本每秒钟将一条消息写入stdout和stderr: test.sh

#!/bin/sh
while [ 0 ]
do
    echo "message to stdout"
    echo "message to stderr" >&2
    sleep 1
done

在我的PHP脚本中,我想运行test.sh并分别处理stdout和stderr: test.php

<?php
$descriptorspec = [
    1 => ['pipe', 'w'], // stdout is a pipe that the child will write to
    2 => ['pipe', 'w'], // stderr is a pipe that the child will write to
];

$command = './test.sh';
$process = proc_open($command, $descriptorspec, $pipes);
// $pipes is now: array(2) { [1]=> resource(i) of type (stream), [2]=> resource(j) of type (stream) }

stream_set_blocking($pipes[1], false);
stream_set_blocking($pipes[2], false);

while (proc_get_status($process)['running']) {
    $read = null;
    $write = $pipes;
    $except = null;
    $stream_select_result = stream_select($read, $write, $except, 1);
    if ($stream_select_result === false) {
        echo "Something went wrong.\n";
        exit(1);
    } elseif ($stream_select_result === 0) {
        echo "Nothing happened.\n";
    } elseif ($stream_select_result > 0) {
        // I WANT TO END UP HERE !!!
        $stdoutline = stream_get_line($pipes[1], 1024, "\n");
        echo "do something with stdout: $stdoutline\n";
        $stderrorline = stream_get_line($pipes[2], 1024, "\n");
        echo "do something different with stderr: $stderrorline\n";
    }
}

fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

我使用php test.php运行我的程序

问题是没有捕获到test.sh的stdout和stderr的消息。 stream_select()的结果始终为0,$ write为空数组。 因此,我的脚本不断回显“什么都没发生。”。

如果我正确理解,则用test.sh将stdout或stderr写入内容时,stream_select()应该捕获。

如何更改脚本test.php以便正确捕获test.sh的stdout和stdout?

0 个答案:

没有答案