Search code examples
mysqlcrondatabase-backups

How do I send cron stderr to a script between pipes?


I have some MySQL databases that I back up nightly from cron, just your standard mysqldump command. I'd like to feed only the errors from mysqldump and/or aws to a script that will then send the error into slack. I'm struggling to figure out how to do that in the middle of the command though. I want to send stderr to slacktee, but stout to gzip and on to aws s3 cp. So this works fine:

* * * * * mysqldump --host=mysql.example.com --user=mysql | gzip | aws s3 cp - s3://backs/backs/whatever.sql.gz

That's just the usual plain ol' backup thing. But I'm trying to squeeze in stderr redirects for the mysqldump command fails, I've tried every combination of 2>&1 I could and each one doesn't do the trick. Every combination either ends with an empty gzip file or stops everything from running.

* * * * * mysqldump --host=mysql.example.com --user=mysql dbname 2>&1 >/dev/null | /usr/local/bin/slacktee | gzip | aws s3 cp - s3://backs/backs/whatever.sql.gz

So if there's an error on the mysqldump command send just the error to /usr/local/bin/slacktee if there's no error, just send the mysqldump output to the pipe over to gzip.

I want the same thing with aws s3 cp, but that seems to be easier, I can just put the redirect at the end.

Edited to add: Ideally I'm hoping to avoid doing a separate script for this and keeping it all in one line in cron.

Also adding another edit. 2>&1 /dev/null was just in this example, I've tried making that 2>&1 /path/to/slacktee as well as different combinations of 2> and 1> and some | in different places as well and every other different way I could think of, and that didn't work either.


Solution

  • I would create a separate script, (mysqlbackup.sh), and change the crontab to:

    * * * * * mysqlbackup.sh
    

    Your script could look like (untested):

    #!/bin/bash
    
    mysqldump --host=mysql.example.com --user=mysql dbname 2>/tmp/errors | gzip > /tmp/mysqldump.gz
    
    if [ -s /tmp/errors ];  # if file has a size
    then
            echo "Something went wrong"
    else
            echo "OK"
    fi
    

    This, of course, needs to be expanded with the aws s3 cp... stuff...