morleyc
morleyc

Reputation: 2431

mysqldump | gzip - $? is always set to 0

I am dumping databases in a loop, if I try and dump a database that doesn't exist I get the stderr mysqldump: Got error: 1049: Unknown database 'yes' when selecting the database as I would expect, however despite the error $? always returns 0.

My code is below:

for database in ${databases[@]}; do
    $dumpcmd $database | gzip > "$backupdir/$database.gz"
    result=$?
    echo "dumped database: $database ($result)"
done

I want to detect an error from mysqldump and print it to the screen - I have a hunch this is related to the pipe to gzip, but as a C# dev trying to learn bash I am stuck!

Upvotes: 2

Views: 1750

Answers (3)

FatalError
FatalError

Reputation: 54551

You want to check what's in PIPESTATUS:

   PIPESTATUS
          An  array  variable (see Arrays below) containing a list of exit
          status values from the processes in  the  most-recently-executed
          foreground pipeline (which may contain only a single command).

So instead of result=$?, try result=${PIPESTATUS[0]}.

Upvotes: 6

scott
scott

Reputation: 2275

You could use this to make sure your dump works before executing your zip:

($dumpcmd $database || echo "$dumpcmd exited with $?" 1>&2) | (gzip > "$backupdir/$database.gz" || echo "echo exited with $?" 1>&2)

or you could set -o pipefail at the beginning of your script to make the pipeline’s return status the value of the last (rightmost) command to exit with a non-zero status, OR zero if all commands in the pipeline exit successfully.

Upvotes: 1

hek2mgl
hek2mgl

Reputation: 157990

That's because $? will give you the return status of the last executed command, what is gzip in this case. But gzip won't care about mysqldump error messages. They are just regular text output for it, which can be compressed.

Change your example to something like this, to become aware of the return status of mysqldump:

for database in ${databases[@]}; do
    # dump to a temporary file
    $dumpcmd $database > temp.sql
    # check mysqldump's return status
    result=$?
    if [ $result != 0 ] ; then
        echo "mysqldump error"
        exit 1
    fi
    gzip temp.sql > "$backupdir/$database.gz"
    echo "dumped database: $database ($result)"
done

Upvotes: 1

Related Questions