Why doesn't this command work as a cronjob, while it works perfectly when typed in a shell? [closed]

If I run this command from the shell, it works as expected:

cd ~ && mysqldump --databases --skip-dump-date --host=localhost --user=admin --password=xxxxx --lock-all-tables --result-file=xxxxx_dump_tmp.sql mydb && gzip xxxxx_dump_tmp.sql && mv xxxxx_dump_tmp.sql.gz xxxxx_dump_`date +"%Y-%m-%d__%H.%M.%S"`.sql.gz

However, if I set up a cronjob with the exact same command (copy-pasted), it fails with the following errors (I receive the notification via email):

/bin/sh: -c: line 0: unexpected EOF while looking for matching ``'
/bin/sh: -c: line 1: syntax error: unexpected end of file

What's wrong?


Solution 1:

What's wrong?

According to man 5 crontab:

«…

The "sixth" field (the rest of the line) specifies the command to be run. The entire command portion of the line, up to a newline or % character, will be executed by /bin/sh or by the shell specified in the SHELL variable of the cronfile. Percent-signs (%) in the command, unless escaped with backslash (), will be changed into newline characters, and all data after the first % will be sent to the command as standard input.

…», you simply have written it wrong. So, for crontab is should be written as date +"\%Y-\%m-\%d__\%H.\%M.\%S"

Solution 2:

  1. Don't put a complex command like this directly in the crontab file.
    Put it in a script and call the script from cron.

    By default cron-jobs get run by sh (unless configured otherwise). When you go through a script you can set the proper shell to use by putting a #!/bin/bash or something along those lines in the first line of the script.

  2. cd ~ is dangerous as hell. It totally depends on under which userid the crontab is running. Not necessarily your own userid !
    So use cd ~userid.

  3. If cron runs as a different user can that user access your home-dir? And has that user the same environment as your account? See also 4.

  4. cron-jobs starts without loading the normal environment. So a lot of normal environment vars (like $PATH) don't exist or just contain limited info. That may cause programs called from cron to fail. See also item 1. You may have to explicitly call your .bashrc (or whatever other startup script you normally use) to setup the proper environment for anything else you put in your cron-called script.