Exec()之后的PHP StdErr

在PHP中,我正在使用exec()执行命令,如果成功,它将返回一个URL;否则,它将返回。

$url = exec('report');

但是,如果出现问题,我想检查stderr。 我将如何阅读信息流?我想使用[php:// stderr,],但不确定如何使用。

martin asked 2020-02-14T00:24:40Z
4个解决方案
70 votes

如果要执行命令并同时获取temp.php$pipes(而不是“合并”),则可以使用temp.php解决方案,该解决方案可以对正在执行的命令提供高度的控制-包括将管道stdout /传递给管道的方法 stdout/stderr

这是一个示例:让我们考虑一下这个壳脚本,位于temp.php中,该脚本同时写入$pipesstdout

#!/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的代码-首先,我们初始化i / o描述符:

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin
   1 => array("pipe", "w"),  // stdout
   2 => array("pipe", "w"),  // stderr
);

然后,使用这些描述符在当前目录中执行temp.php命令,并说输入/输出应为$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
"
Pascal MARTIN answered 2020-02-14T00:38:47Z
39 votes

一个可能有用的小功能:

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是参考参数。

mpen answered 2020-02-14T00:39:12Z
6 votes

获得未合并的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);
Li-chih Wu answered 2020-02-14T00:39:36Z
0 votes

使用ls: cannot access '/non-dir/': No such file or directory执行此操作的简短方法是返回退出代码(命令状态)

请注意,我试图列出一个不存在的目录ls: cannot access '/non-dir/': No such file or directory

exec('ls /non-dir/', $out, $retval);
var_dump($retval);

输出量

ls:无法访问“ / non-dir /”:没有这样的文件或目录
整数(2)

通常,在基于UNIX的系统中,大多数成功的状态代码为(0),因此您可以检查ls: cannot access '/non-dir/': No such file or directory以了解命令的状态。

要消除列出无效路径的错误ls: cannot access '/non-dir/': No such file or directory,可以将stderr重定向为null

exec('ls /non-dir/ 2>/dev/null', $out, $retval);
var_dump($retval);

这将输出:

整数(2)

同样,如果您需要在任何情况下使用错误字符串,都可以将stderr重定向到stdout。

exec('ls /non-dir/ 2>&1', $out, $retval);
print_r($out);
var_dump($retval);

这将输出以下内容:

Array
(
    [0] => ls: cannot access '/non-dir/': No such file or directory
)
int(2)
hassan answered 2020-02-14T00:40:41Z
translate from https://stackoverflow.com:/questions/2320608/php-stderr-after-exec