Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP StdErr after Exec()

Tags:

php

stderr

exec

In PHP I am executing a command with exec(), and it returns if successful an 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.

like image 954
martin Avatar asked Feb 23 '10 18:02

martin


3 Answers

If you want to execute a command, and get both stderr and 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.

And here is an example : let's consider we have this shell-script, in test.sh, which writes to both stderr and 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 :

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

And, then, execute the test.sh command, using those descriptors, in the current directory, and saying the i/o should be 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.php script :

$ 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 " 
like image 156
Pascal MARTIN Avatar answered Sep 20 '22 12:09

Pascal MARTIN


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.

like image 35
mpen Avatar answered Sep 21 '22 12:09

mpen


The short way to do such a things with exec is to return the exit code ( status of the command )

Note that I am trying to list a non-exists directory /non-dir/

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

Output

ls: cannot access '/non-dir/': No such file or directory
int(2)

Normally in unix-based system most of successful statuses codes is ( 0 ) so you can check your $retval to know the status of the command.

to dismiss the error from listing an invalid path ls: cannot access '/non-dir/': No such file or directory you can redirect your stderr to null

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

this will output :

int(2)

also if you need the error string to use it in any scenario you may redirect your stderr to the 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)
like image 38
hassan Avatar answered Sep 22 '22 12:09

hassan