2011-01-07

Bash - How to check the exit status of pipe command


Piping in bash commands are common.
Checking exit status of a command in bash scripting is essential.
How about checking exit status of the commands in a pipe?





Example:

mysqldump -u $db_username -p $db_name | gzip -c > output.sql.gz

One would just check the exit status of the above using :
echo $?

But the exit status will always be "0" as that's the exit status of the last command, which is the "gzip -c > output.sql.gz".

In order to check the exit status of a particular command in the "pipe command", examine the bash special array, "PIPESTATUS". That's where bash store exit status of the recent command from a pipe.
E.g. :
  1. ${PIPESTATUS[0]} refers to the first command in the "pipe command"
  2. ${PIPESTATUS[1]} refers to the second command in the "pipe command"
  3. ${PIPESTATUS[2]} refers to the third command in the "pipe command"
and so on

Here's an example of how to check a program exit code in a pipe command :
#!/usr/local/bin/bash

db_username="myusername"
db_name="mydatabase"

mysqldump -u $db_username -p $db_name | gzip -c > ./output.sql.gz;

if [ ${PIPESTATUS[0]} -ne "0" ];
then
    echo "the command \"mysqldump\" failed with Error: ${PIPESTATUS[0]}";
    exit 1;
else
    echo "Database dump successfully!";
fi

Shalom !!!

ref : Bash manual - PIPESTATUS

2 comments:

Biju said...

Thank you so much!
I was scratching my head over the exit status of
netstat -ntap | grep sshd
in a bash script, to find if ssh service is running. And i would get exit status 0 evrytime even when ssh was down.

brk3 said...

The $PIPESTATUS variable is a great tip :)

There's a small bug with the example though, once you access PIPESTATUS it gets overwritten:

$ false
$ echo $PIPESTATUS[0]
1[0]
$ echo $PIPESTATUS[0]
0[0]

This essentially means you'll always get "failed with error 0" in the event of a failure.

Do it like this:

mysqldump -u $db_username -p $db_name | gzip -c > ./output.sql.gz;
MYSQL_RET=${PIPESTATUS[0]}

if [ ${MYSQL_RET} -ne "0" ];
etc...