Если вы хотите выполнить команду и получить и stderr
, и stdout
, а не "объединенные", решение, вероятно, будет использовать proc_open
, что обеспечивает высокий уровень контроля над выполняемой командой, включая способ передачи stdin
/ stdout
/ stderr
.
И вот пример: давайте рассмотрим, что у нас есть этот скрипт-сценарий, в test.sh
, который записывает и в stderr
, и в stdout
:
#!/bin/bash
echo 'this is on stdout';
echo 'this is on stdout too';
echo 'this is on stderr' >&2;
echo 'this is on stderr too' >&2;
Теперь давайте кодируем некоторый PHP на temp.php
- сначала мы инициализируем дескрипторы ввода / вывода:
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w"), // stderr
);
И затем выполните команду test.sh
, используя эти дескрипторы, в текущем каталоге и заявив, что ввод / вывод должен быть от / до $pipes
:
$process = proc_open('./test.sh', $descriptorspec, $pipes, dirname(__FILE__), null);
Теперь мы можем читать из двух выходных каналов:
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
И, если мы выведем содержимое этих двух переменных:
echo "stdout : \n";
var_dump($stdout);
echo "stderr :\n";
var_dump($stderr);
При выполнении сценария temp.php
мы получаем следующий вывод:
$ php ./temp.php
stdout :
string(40) "this is on stdout
this is on stdout too
"
stderr :
string(40) "this is on stderr
this is on stderr too
"