• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1476
  • Last Modified:

PHP shell_exec - some commands return STDERR and STDOUT, others do not (mysqldump)

I'm trying to create a simple PHP script which exports a MySQL database to a file and imports it back into a different database (recreating the test db from live). I'm using PHP's shell_exec with mysqldump and mysql commands. I have something wrong in my script because it isn't working as expected, but I can't seem to make it output the error to the screen.

I read up and found I needed to add " >2&1" to the end of my command to pipe STDERR to STDOUT which should force everything to the screen, but this only seems to be effective for some commands and not others. For example, if I use "ls" with bad arguments I get the error to the screen, and if I use it with good arguments I get a directory listing. If I use mysqldump with bad arguments I get an error to the screen, but if I use it with well-formed arguments that just happen to be incorrect values (e.g. wrong password), I get nothing back, whilst the same command from SSH tells me what went wrong.

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'));

Open in new window

0
wwarby
Asked:
wwarby
  • 3
  • 2
1 Solution
 
CSecurityCommented:
shell_exec('mysqldump --user=wrong --password=wrong wrongdb > tmp.sql 2>&1');

$filename = "tmp.sql";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo $contents;
unlink('tmp.sql');
0
 
CSecurityCommented:
Here is with check for errors:


shell_exec('mysqldump --user=wrong --password=wrong wrongdb > tmp.sql 2>&1');

$filename = "tmp.sql";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);

$pos = strpos($contents, "Got error");

if ($pos == false)
echo "Mysqldump was successfull";
else
{
echo $contents;
unlink('tmp.sql');
}

Open in new window

0
 
wwarbyAuthor Commented:
CSecurity,

Thanks very much for this - I will test it and I'm sure it probably will work - my only gripe is that I actually want to string together quite a number of commands so in an ideal world I wouldn't be writing the output to a file, reading it back and deleting it once for each command. If this is the best/only way to go then it's exactly what I'll do, just wanted to first check with you that there isn't a way that doesn't involve writing to disk?
0
 
CSecurityCommented:
No... As mysqldump dumps database into STDOUT, you have to write it to file using > char.

So if command fails, failure string will go to same file.

1) You can write a PHP code to connect mysql with given user/pass, if failed show error message and don't let mysqldump command to be executed with wrong credentials.

2) You have to use method I mentioned.

3) Write a PHP code to dump db to a file.

0
 
wwarbyAuthor Commented:
Sincere apologies for not accepting this response sooner - I must confess I forgot to come back and accept the solution until I was prompted by an email reminder. Your solution worked just fine, thanks very much!
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now