В PHP я выполняю команду с exec (), и она возвращает в случае успешного URL-адреса;
$url = exec('report'); 
Тем не менее, я хочу проверить stderr, если что-то пошло не так. Как бы я прочитал поток? Я хочу использовать php: // stderr, но я не уверен, как его использовать.
  Если вы хотите выполнить команду и получить как stderr и stdout , а не «слияние», решение, вероятно, будет использовать proc_open , что обеспечивает отличный уровень контроля над исполняемой командой, включая способ подключения stdin / stdout / stderr . 
  И вот пример: давайте рассмотрим, что у нас есть этот shell-скрипт в 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; 
  Теперь давайте temp.php некоторый PHP, в temp.php – во-первых, мы инициализируем дескрипторы temp.php : 
 $descriptorspec = array( 0 => array("pipe", "r"), // stdin 1 => array("pipe", "w"), // stdout 2 => array("pipe", "w"), // stderr ); 
  И затем выполните команду test.sh , используя эти дескрипторы, в текущем каталоге и test.sh , что i / o должен быть от / до $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 " 
Надеюсь это поможет 🙂
Небольшая функция, которая может быть полезна:
 function my_shell_exec($cmd, &$stdout=null, &$stderr=null) { $proc = proc_open($cmd,[ 1 => ['pipe','w'], 2 => ['pipe','w'], ],$pipes); $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[2]); return proc_close($proc); } 
Код возврата возвращается, а STDOUT и STDERR являются ссылочными параметрами, если они вам понадобятся.
Другой способ получить unmerged stdout / stderr.
 $pp_name = "/tmp/pp_test"; @unlink($pp_name); posix_mkfifo($pp_name, 0777); $pp = fopen($pp_name, "r+"); stream_set_blocking($pp, FALSE); exec("wget -O - http://www.youtube.com 2>$pp_name", $r_stdout); $r_stderr = stream_get_contents($pp); var_dump($r_stderr); fclose($pp); unlink($pp_name); 
Если вы хотите игнорировать stdout и получать только stderr, вы можете попробовать следующее:
 exec("wget -O - http://www.youtube.com 2>&1 >/dev/null", $r_stderr);