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 = [
   0 => ["pipe", "r"],  // stdin
   1 => ["pipe", "w"],  // stdout
   2 => ["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
"
Answer from Pascal MARTIN on Stack Overflow
🌐
PHP
php.net › manual › en › function.shell-exec.php
PHP: shell_exec - Manual
Here is a easy way to grab STDERR and discard STDOUT: add '2>&1 1> /dev/null' to the end of your shell command For example: <?php $output = shell_exec('ls file_not_exist 2>&1 1> /dev/null'); ?>
Top answer
1 of 6
93

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 = [
   0 => ["pipe", "r"],  // stdin
   1 => ["pipe", "w"],  // stdout
   2 => ["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
"
2 of 6
65

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.

Discussions

PHP - How to get Shell errors echoed out to screen - Stack Overflow
Why is this info not being passed back to my PHP script so I can echo it out? ... You could try to append 2>&1 at the end of the command to redirect the error message to the standard output ... The error data is output from the target program's STDERR stream. You can get access to the error data through the normal returned string from shell_exec... More on stackoverflow.com
🌐 stackoverflow.com
php - getting output and exit status from shell_exec() - Stack Overflow
When doing something like $output = shell_exec("command 2>&1"); collecting the command's stdout & stderr in $output, is there a way to find the command's exit status? One could write the More on stackoverflow.com
🌐 stackoverflow.com
Executing a shell command from PHP with shell_exec - Unix & Linux Stack Exchange
Included in my thesis is to create an administration interface, in which an administrator can approve users whom have asked for access to use OpenNebula. Upon approval the users should be added to More on unix.stackexchange.com
🌐 unix.stackexchange.com
June 19, 2011
shell - PHP shell_exec() vs exec() - Stack Overflow
Try adding 2>&1 to the end of your command to redirect STDERR to STDOUT if you're on a linux machine. 2013-03-11T21:06:03.137Z+00:00 ... I have addedd it also . But still I am getting 0 as the value. I have used one wc -l command and if the file is not there, I need to get the error message saying No such file or directory. 2013-03-12T04:02:27.69Z+00:00 ... The difference is that with shell_exec ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
LornaJane
lornajane.net › posts › 2007 › seeing-stderr-from-php-exec
Seeing stderr from PHP exec() | LornaJane
July 27, 2007 - When you look at the output of the exec call, it isn’t the same as what you would see on the screen when typing the command. PHP returns you the content from stdout, but if anything goes wrong it will go to stderr which PHP doesn’t provide.
🌐
Web Design Singapore
24k.com.sg › blog › how-to-get-error-channelstderr-using-shell-exec-in-php
How to get error channel(stderr) using shell_exec in PHP?
December 1, 2010 - I didn't find obvious function that can return the results in stderr. So shell_exec is a general solution. It's not some special function, but just something standard in shell. The answer is "2>&1". It means redirect message in stderr into stdout.
Price   $3 - $100
Call   68440132
Address   61 Upper Paya Lebar Road #05-02, 534816, Singapore
🌐
H|ard|Forum
hardforum.com › bits & bytes › webmastering & programming
PHP exec() grabbing stdout+stderr | [H]ard|Forum
August 17, 2006 - NOT dead anymore! So, I figured out how to grab both stdout and std err by doing 2>&1, and that exposed the real problem. There is an application that is called through the exec() call and it turns out that I cannot execute it through PHP. The error message I get is "esql: cannot...
🌐
Google Groups
groups.google.com › g › comp.lang.php › c › 2HPTzUKARNU
redirect stdout and stderr to PHP variables?
STDOUT is what PHP produces and is returned to the client (most of the time with a webserver inbetween). STDERR is where PHP directs its erorrs to. (Think logfile, and/or to STDOUT: this is all configurable.) But you don't see STDIN/STDOUT/STDERR when you work with PHP without using exec().
🌐
Darklaunch
darklaunch.com › php-exec-stderr-stdout-return-code.html
PHP exec() + stderr, stdout, & return code - Dark Launch
March 21, 2013 - Run a command in php and get standard output (stdout), standard error (stderr), and the return code / return value. function pipe_exec($cmd, $input='') { $proc = proc_open($cmd, array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')), $pipes); fwrite($pipes[0], $input); fclose($pipes[0]); $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[2]); $return_code = (int)proc_close($proc); return array($return_code, $stdout, $stderr); }
Find elsewhere
🌐
Bytes
bytes.com › home › forum › topic › php
capture STDERR in exec() - PHP - Bytes
November 2, 2015 - ' 2>&1', $output, $return); Well, ... = exec($command . ' 2>&1', $outarr, $return); No joy. Even though $return was set to the error value, $outarr was empty as was $output. My command was 'ls -l doesn't_exist', which nicely produces an error on STDERR when run from the shell...
Top answer
1 of 2
5

Update and answer for the benefit of anyone who comes here with a similar issue.

After spending a lot of time on this I gave up with exec() and gave proc_open() a try instead.

Doing it this way now works locally and on the server:

<?php
$cmd = "__test.bat";

$descriptorspec = array(
    0 => array("pipe", "r"), // STDIN
    1 => array("pipe", "w"), // STDOUT
    2 => array("pipe", "w"), // STDERR
);
$cwd = getcwd();
$env = null;

$proc = proc_open($cmd, $descriptorspec, $pipes, $cwd, $env);
if (is_resource($proc)) {
    // Output test:
    echo "STDOUT:<br />";
    echo "<pre>".stream_get_contents($pipes[1])."</pre>";
    echo "STDERR:<br />";
    echo "<pre>".stream_get_contents($pipes[2])."</pre>";
    $return_value = proc_close($proc);
    echo "Exited with status: {$return_value}";
}
?>

For some reason, missing out the getcwd() part causes the command to fail on the server unless I specify the complete path, whereas locally that is not an issue.

With this method I can append 2>&1 to redirect all output to STDIN. To output to a file, the manual shows that the $descriptorspec array can be modified e.g: 2 => array("file", "stderr.log", "a") (I have not yet tested this though)

One difference here is that if I want to retrieve the output in PHP, rather than getting all of the lines in an array, I need to read from the streams using stream_get_contents().

I still don't understand why there was an issue with using exec(), but this method seems to work both locally and on the server - If anyone knows why this could be, please let me know!

2 of 2
3

$o = null; $r = null; exec("php test.php 2>&1", $o, $r ); It's quite simple

🌐
Experts Exchange
experts-exchange.com › questions › 24993565 › PHP-shell-exec-some-commands-return-STDERR-and-STDOUT-others-do-not-mysqldump.html
Solved: PHP shell_exec - some commands return STDERR and STDOUT, others do not (mysqldump) | Experts Exchange
December 21, 2009 - It's as though mysql and mysqldump are somehow asynchronous, and the output returns after shell_exec has already returned, but I don't think that actually is the case. Points awarded to the first person who can make the last line of my code sample output it's error to the screen in PHP. //This will write STDERR to screen echo(shell_exec('ls idontexist 2>&1')); //This will write STDERR to screen echo(shell_exec('mysqldump -badarguments 2>&1')); //This will write nothing to screen echo(shell_exec('mysqldump --user=wrong --password=wrong wrongdb > tmp.sql 2>&1'));
🌐
Ui
php.kambing.ui.ac.id › manual › en › function.shell-exec.php
PHP: shell_exec - Manual
This can be worked around by doing anything like the following: shell_exec ("silentcmd && echo ' '"); Here we're simply outputting blank whitespace if the command succeeds - which satisfies this slightly strange issue. From there, you can trim() the command output etc.
🌐
Uptimia
uptimia.com › home › questions › what is the difference between shell_exec() and exec() in php?
What Is The Difference Between Shell_exec() And Exec() In PHP?
November 17, 2024 - PHP has several functions for running ... to run external commands from their PHP scripts. The shell_exec() function returns all output from the executed command as a string. This includes standard output (stdout) and standard error (stderr)....
🌐
GitHub
gist.github.com › lyoshenka › 4a861672cf36ece4d09c
Proper PHP shell exec function. Gets you the return code, stdout, and stderr. Plus lets you you stream the output to stdout/stderr in addition to capturing it. · GitHub
Proper PHP shell exec function. Gets you the return code, stdout, and stderr. Plus lets you you stream the output to stdout/stderr in addition to capturing it. - shellExec.php