我想创建一个运行命令行管理程序或程序并捕获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?