Seeing stderr from PHP exec()

Today I was using the PHP command exec() in a script, which runs whatever you pass to it as it you had typed it on the command line. Its possible to check both the output of the command and the return value, which I did since I wasn’t getting the results I expected.

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.

Redirect stdout to stderr

To get around this problem I altered my call from this:


exec ('unzip '.escapeshellarg($filename));

to this:


exec('unzip '.escapeshellarg($filename).' 2>&1);

This collection of characters tacked on the end of the code tells the system to send output 2 (stderr) to the address of output 1 (stdout). And the upshot is that I started to see the error messages being returned by the unzip program.

Postscript

Not really relevant to my point but probably useful for reference – the actual problem was that unzip was returning 50 as its return value. This apparently means the disk is full, which it wasn’t.

What had happened was that I was unzipping a file in another directory and unzip was trying to place the contents into my current working directory rather than the one with the zip file in! I used the -d switch to unzip to direct the inflated files to the right place and this worked a treat.

9 thoughts on “Seeing stderr from PHP exec()

  1. Hi Geoff :) I don’t think proc_open is the command I want in this scenario as I don’t want to operate on the file afterwards. I also like exec() because its widely used so won’t confuse the maintainers who have to look at the code after me!

    • Will this pass a live stream of data back to the php script?

      I want to be able to display what is happening when i execute a large script rather than the php hanging and then displaying all the data in one lump.

  2. Greg: I think its just a return value rather than being able to be handled as a stream. Depending what the application is, you might like to split the large script into batches or something in order to give progres updates to the user?

  3. What if….
    [code]
    exec(“mysqldump -d -u my_user -pmy_pass my_invalid_database > dump.sql 2>&1”, $output_array, $error_level);
    [/code]

    It doesnt get the error, or I’m wrong at some point?

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

This site uses Akismet to reduce spam. Learn how your comment data is processed.