0

On my Ubuntu 18.04 command-line, this works perfectly:

mysqldump --user="myuser" --password="mypassword" --skip-lock-tables --single-transaction --no-tablespaces  mydb | gzip > /home/userhome/database_backup.sql.gz

So I create a PHP script having exact same (as a troubleshooting step):

exec("mysqldump --user=\"myuser\" --password=\"mypassword\" --skip-lock-tables --single-transaction --no-tablespaces  mydb | gzip > /home/userhome/database_backup.sql.gz", $output, $worked);

switch($worked){
    case 0:
        echo "database backed up successfully";
        break;
    case 1:
        echo "database back up failed";          
        break;
}

var_dump($output);

Script outputs:

database back up failed
array(0) { }

How do I resolve this especially with no useful error given in output?

Been through this and this but none of these apply. I have checked permissions and database access passwords and all seem ok.

user1729972
  • 712
  • 2
  • 9
  • 29
  • In your exec, replace `mysqldump` by `/usr/bin/mysqldump` and retry (if still fails, make sure that mysqldump is executable by httpd) – Ken Lee Jul 04 '21 at 10:43
  • where can I read up on making mysqldump executable by httpd? – user1729972 Jul 04 '21 at 10:55
  • Well, why do you ask about executable? You've written that you've checked the file modes already per the second "this" link in your question and said file-modes would not apply .... ??? – hakre Jul 04 '21 at 12:13
  • Maybe it helps if you [put the error messages into the output](https://stackoverflow.com/q/3863699/367456)? – hakre Jul 04 '21 at 12:32
  • 1
    The code you show doesn't run. It generates: `PHP Parse error: syntax error, unexpected identifier "myuser"` because you have double-quotes for shell arguments within your double-quoted PHP string. – Bill Karwin Jul 04 '21 at 17:07

3 Answers3

0

You can even see in the highlighting syntax of stackoverflow that you have to escape your quotes. First step is to fix that and then see what else might be wrong:

exec('mysqldump --user="myuser" --password="mypassword" --skip-lock-tables --single-transaction --no-tablespaces  mydb | gzip > /home/userhome/database_backup.sql.gz', $output, $worked);
Laurens
  • 2,596
  • 11
  • 21
0

The command might be the same, but the environment is likely different.

Some pointers:

  • the user executing the command
  • the environment in which the command is executed
  • the working directory
  • the shell (phps' exec is using the standard shell, e.g. /bin/sh on linux)
  • the handling of the standard-error stream (stderr)

To look for diagnostic error messages, check with the standard error channels of the PHP SAPI in use when executing the PHP script. This could be the server error log or when you execute the script in CLI you see the diagnostic messages directly via your TTY.

For quick introspection, a viable scenario could be to execute the script (or an excerpt) with the PHP CLI SAPI under the same user as the webserver, see su(1).

To harmonize some more of the points in the list above at once, a shell script can be useful. It can specify the shell to use, control the shells options, assert the environment and working directory, check pre-conditions like access for the current user and even handle other diagnostics. It can also help in defining light-weight processes. Technically there is no must nor a should to have such a shell-script if you get the command just working, e.g. by locating the diagnostic messages and fixing any issues.

To streamline standard error into $output with exec, so to intermix diagnostics with output, please see:

It comes with the caveat that you have to change your program only to obtain diagnostic messages which is not what you normally want (it leads to more cumbersome "solutions") - but might be appropriate for troubleshooting none the less, e.g. in your case as the output is redirected to file already and $output then contains diagnostics messages only.

hakre
  • 193,403
  • 52
  • 435
  • 836
0

In the end this had something to do with permissions despite the fact that there was no clear error message initially; comments and replies to this post all pointed me to do further searches, thanks.

On setting up variables and switching the exec string literal to:

"mysqldump --user={$dbUser} --password={$dbPass} --host={$dbHost} --skip-lock-tables --single-transaction --no-tablespaces  {$dbname} --result-file={$backupFile} 2>&1"

it now gave a clear "permission denied" error.

I simply set the folder to 777, to enable this go through for now and will work on narrowing down the permissions later. Not sure what's magical about the cryptic 2>&1 but will research that too.

user1729972
  • 712
  • 2
  • 9
  • 29