Я хочу создать сценарий PHP CLI, который запускает сценарий оболочки или программу и перехватывает stdout и stderr.
Не удается заставить работать 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
Проблема заключается в том, что сообщения на stdout иstderr test.sh не фиксируется.Результат stream_select () всегда равен 0, а $ write - пустой массив.Так что мой сценарий повторяет «Ничего не произошло».
Если я правильно понимаю, stream_select () должен перехватывать, если что-то записано в stdout или stderr test.sh.
Как мне изменить свой сценарийtest.php, чтобы он правильно захватывал stdout и stdout test.sh?