Exec() 后的 PHP StdErr
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2320608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP StdErr after Exec()
提问by martin
In PHP I am executing a command with exec(), and it returns if successful an URL;
在 PHP 中,我使用 exec() 执行命令,如果成功则返回 URL;
$url = exec('report');
However, I want to check stderr, if something went wrong. How would I read the stream? I want to use php://stderr, but I am not sure how to use it.
但是,如果出现问题,我想检查 stderr。我将如何阅读流?我想使用 php://stderr,但我不确定如何使用它。
回答by Pascal MARTIN
If you want to execute a command, and get both stderrand stdout, not "merged", a solution would probably to use proc_open, which provides a great level of control over the command that's being executed -- including a way to pipe stdin/stdout/stderr.
如果你想执行一个命令,并同时获得stderr和stdout,而不是“合并”,一个解决办法可能是使用proc_open,它提供了真实执行过的命令控制的一个伟大的水平-其中包括如何管stdin/ stdout/ stderr。
And here is an example : let's consider we have this shell-script, in test.sh, which writes to both stderrand stdout:
这是一个例子:让我们考虑一下我们有这个 shell 脚本 in 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;
Now, let's code some PHP, in temp.php-- first, we initialize the i/o descriptors :
现在,让我们编写一些 PHP 代码,temp.php首先,我们初始化 i/o 描述符:
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w"), // stderr
);
And, then, execute the test.shcommand, using those descriptors, in the current directory, and saying the i/o should be from/to $pipes:
然后,test.sh在当前目录中使用这些描述符执行命令,并说 i/o 应该是 from/to $pipes:
$process = proc_open('./test.sh', $descriptorspec, $pipes, dirname(__FILE__), null);
We can now read from the two output pipes :
我们现在可以从两个输出管道中读取:
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
And, if we output the content of those two variables :
而且,如果我们输出这两个变量的内容:
echo "stdout : \n";
var_dump($stdout);
echo "stderr :\n";
var_dump($stderr);
We get the following output when executing the temp.phpscript :
执行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
"
回答by mpen
A little function that might be helpful:
一个可能有用的小功能:
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);
}
The exit code is returned and STDOUT and STDERR are reference params if you need them.
如果需要,将返回退出代码,并且 STDOUT 和 STDERR 是参考参数。
回答by Li-chih Wu
Another way to get 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);
If you want to ignore stdout and get only stderr, you can try this:
如果你想忽略 stdout 而只得到 stderr,你可以试试这个:
exec("wget -O - http://www.youtube.com 2>&1 >/dev/null", $r_stderr);
回答by hassan
The short way to do such a things with execis to return the exit code ( status of the command )
做这样的事情的简短方法exec是返回退出代码(命令的状态)
Note that I am trying to list a non-exists directory /non-dir/
请注意,我正在尝试列出一个不存在的目录 /non-dir/
exec('ls /non-dir/', $out, $retval);
var_dump($retval);
Output
输出
ls: cannot access '/non-dir/': No such file or directory
int(2)
ls: 无法访问 '/non-dir/': 没有这样的文件或目录
int(2)
Normally in unix-based system most of successful statuses codes is ( 0) so you can check your $retvalto know the status of the command.
通常在基于 unix 的系统中,大多数成功的状态代码是 ( 0),因此您可以检查$retval以了解命令的状态。
to dismiss the error from listing an invalid path ls: cannot access '/non-dir/': No such file or directoryyou can redirect your stderrto null
要消除列出无效路径的错误,ls: cannot access '/non-dir/': No such file or directory您可以将stderr重定向到 null
exec('ls /non-dir/ 2>/dev/null', $out, $retval);
var_dump($retval);
this will output :
这将输出:
int(2)
整数(2)
also if you need the error string to use it in any scenario you may redirect your stderrto the stdout.
此外,如果您需要错误字符串在任何情况下使用它,您可以将您的stderr重定向到stdout。
exec('ls /non-dir/ 2>&1', $out, $retval);
print_r($out);
var_dump($retval);
this will output the following:
这将输出以下内容:
Array
(
[0] => ls: cannot access '/non-dir/': No such file or directory
)
int(2)

