php : Capturing the command output - php

I am using exec function to execute the specific executable files in php .
exec ( $file , $output , $return_value ) ;
When the given file executed successfully I am able to get the output in the second argument
by checking the return values , So, It is working fine. But My requirement is when the command execution getting failed due to some reason. I need to get that error message of that executed program . What I need to do to get the error . through second argument we can get the successful output only . Not error message.
Thanks.

The second argument $output only captures STDOUT from your executable. Error messages are usually sent to STDERR so that they easily can be written to an error log or similar, but this means that you won't see them when you call exec.
If this is a linux system, you could append 2>&1 to your command, in order to redirect STDERR to STDOUT. I haven't tried this, but it should forward the error messages to your $output variable.
Edit:
I've read up on it on www.php.net/exec, and it seems this would work.
exec($file.' 2>&1', $outputAndErrors, $return_value);
It is also possible to redirect the errors to a temporary file and read them separately.
exec($file.' 2> '.$tmpFile, $outputOnly, $return_value);
Edit 2
It seems windows also uses this Bourne style output redirecting syntax, so the examples should work for windows too.
More on input and output streams

If you need to keep stderr and stdout separate, try proc_open:
http://php.net/manual/en/function.proc-open.php

The $return_value will have the error code returned by the program which should be meaningfull enough, I don't think you can have better.

Related

PHP on Windows using system function - Why errors not in the correct place

I am using the PHP system function on windows as follows:
system("mysql --user=root --password=xxxx --host=127.0.0.1 --verbose <create.sql > out.txt 2>&1", $retVal);
But the error messages apppear at the top of the file. Is it possible to get the error messages to appear after the appropriate line of SQL that has the error.
The problem is that stdout is buffered and stderr is not meaning that the errors will always show first in this case. You are going to need to wrap your system call in a script and sort it afterwards if you wish to retain some sort of order. There is some explanation available over here.

Error message from php executing c script

I spent hours trying to debug a php script which runs a c simulation using exec(). After throwing stderr print messages in everywhere, I finally found that the underlying issue was printing a directory path to a char array that was too small using sprintf().
I'm guessing it was a segmentation fault, but I never actually saw the shell error message saying 'segmentation fault'. When I changed the allocation size, everything worked.
I had been redirecting stderr output to a log file, and that log file got all of the messages from fprintf(stderr,"..."); but it didn't get any shell error messages.
The command is this
exec("$cmd 2>> $logFile & $PROCFILE 1 $ipaddr $! 2>> $logFile", $output, $rv);
$cmd runs a c simulation, and $PROCFILE runs a second c program that takes three arguments (the 1, $ipaddr, and $!). Before I fixed the allocation size problem, the php script would just stop execution of the $cmd simulation and continue on the next line (i.e. after the exec() statement). The next line in the php file is
if(rv!=0){handle error}
but that also didn't catch the problem.
I kept thinking I was running into a permissions error. How can one get exec() to show the shell errors? Or was this a result of running the two programs simultaneously with '&'?
When a program dies, the "Segmentation fault" message comes from the shell, not from the program. Redirection only applies to the program's output, not the shell's. The message should get put into the $output variable. If $rv is 0 and there's nothing in $output, I suspect you're wrong about what happened. I suggest you verify this by writing a simple test program that just does:
kill(0, SIGSEGV);
BTW, why aren't you using snprintf(), so you can't get a buffer overflow in the first place?

catch postgresql command execution error from php file

I m a begineer in php and having some problem as :
I have a php file having a function create_dump() in which I am dumping my postgresql database using pg_dump command. Now while executing php file from linux terminal it asks for postgresql password on terminal. I want to add error handling in my php file if user provides wrong password for the database unintentionally.
In other words :
How to catch pg_dump (postgresql command) execution error from my php file ?
Thanks !
Based on the info you provided I have a workaround for what you want to do. First, instead of piping the output of your dump using the '>' you will need to use the --file=some_file.sql flag instead which does the same job.
Now, it does not appear that the $output from the passthru call will capture the output even if you send stderr to stdout so here's what would work. You would modify the command using the --file= flag and pipe the output of the command (which contains the error) to a log file while making sure to also send stderr to stdout (do 2>&1 after the command) in order to capture the error.
Here's the code:
// notice the file= flag and the piping of error to the file
$command=
"/usr/bin/pg_dump --a --no-owner --no-acl --attribute-inserts ".
"--disable-dollar-quoting --no-tablespaces ".
"--file={$path['schema_path']}schema-{$latest_update}.sql ".
"--host={$db['hostname']} --user={$db['username']} ".
"--password --port={$db['port']} {$db['database']} > pg_dump_error.log 2>&1";
// no output to capture so no need to store it
passthru($command);
// read the file, if empty all's well
$error = file_get_contents('pg_dump_error.log');
if(trim($error) != '')
exit("PG_DUMP ERRROR:\n-----\n$error\n");
Hope this is more or less what you were looking for.

ImageMagick compare not returning anything to php shell_exec()

I want to compare two images using Image Magick. For this I am using following command in windows command prompt
compare -verbose -metric mae image1.jpg image2.jpg difference.png
This command compares image1 and image2 and prints the resultant output to command prompt window and generates a difference.jpg file that shows difference between two images.
But when I run same command using php shell_exec() no output is returned. I know that the command is being executed by php as difference.jpg is being generated but no output is returned by the function. Similarly when i try passthrough() or system() to get output, again the command is being executed but no output is returned.But when I use builtin system commands like dir I can easily get output.
Any help will be appreciated as I am stuck on this for hours but still no success Thanks
I solved the problem. Its strange that imagemagick compare with verbose arguement does not send anything to normal command promt output. It sends output to stderr. Stderr normally receives error output. But here this command is writing normal output to stderr. As output is going to stderr so shell_exec() is unable to get it. In order to capture it in shell_exec() we will have to append 2>&1 to command. This will redirect stderr to normal command prompt output.
The ImageMagick compare command normally doesn't produce any output. You give it two input files and the name of the output file, and it quietly creates the output file.
If there's an error, it will write an error message to stderr and set a non-zero exit status. (There should be a way to get the exit status, but I don't know PHP.)

Php system() / exec() don't return output

For common commands like 'ls', exec() works fine, eg:
exec('ls',$output,$retval);
var_dump($output,$retval);
// $output contains an array of filenames, and retval === 0
But when trying to execute another program, I can't get the output:
exec('some_command --a_parameter',$output,$retval);
var_dump($output,$retval);
// $output contains an empty array, end $retval === 0
This command prints some lines when executing it directly from the command-line though.
I know the command has been successful because of the results (some files updated, data added, etc), and yet I can't see the output.
Any ideas?
It sounds like the program is outputting its warnings to standard error rather than standard output. exec will only catch standard output. I don't know for certain that standard error is always sent to the apache error log, but it seems likely.
If you don't need compatibility with non-*nix systems, you can redirect standard error to standard output by appending 2>&1 to the command:
exec('some_command --option 2>&1', $output, $ret);
This should both make the warnings available to your php program and prevent unnecessary logging.
All the output was being sent to httpd/error_log when for some * reason, when the application found a warning (something internal, not even fatal)
My solution: When there is no output, assume it failed.
My apache logs are going to get dirty, but whatever.

Categories