在PHP中,我使用exec()执行一个命令,并且在成功的情况下返回一个URL;Exec后PHP StdErr()
$url = exec('report');
但是,我想检查stderr,如果出了问题。我如何阅读流? 我想使用php:// stderr,但我不确定如何使用它。
在PHP中,我使用exec()执行一个命令,并且在成功的情况下返回一个URL;Exec后PHP StdErr()
$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;
现在,让我们一些代码PHP,在temp.php
- 首先,初始化I/O描述符:
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w"), // stderr
);
,然后,执行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
"
希望这有助于:-)
使用这个时,确保所有的人都使用proc_close,当你完成清洁的时候。 – 2011-10-27 21:45:40
为什么你将结果重定向到一个进程var? – 2012-11-07 12:53:32
@BriceFavre他把它放在一个进程变量中,以便他可以稍后用proc_close关闭它,这也将返回进程退出的返回代码。 '$ returnCode = proc_close($ process);' – 2013-03-04 20:15:58
另一种方式来获得未合并标准输出/标准错误。
$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);
如果你想忽略标准输出并获得唯一标准错误,你可以试试这个:
exec("wget -O - http://www.youtube.com 2>&1 >/dev/null", $r_stderr);
一个小功能可能会有所帮助:
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是参考参数。
不错,简单,完美。感谢发布! – 2015-01-07 21:56:00
我会推荐你使用Symfony/Process组件。 – 2018-02-06 18:03:35