Yesterday I was re-working a database backup script at one of my customers and stumbled onto a problem when I wanted to have both proper error handling and at the same time avoid filling the disk.
The code providing the challenge was this
$MYSQLDUMP $MYSQLDUMP_OPTS $DB | gzip -9 > $BACKUP_FILEI need to pipe the output of mysqldump to gzip, because otherwise I run into problems with the disk filling up. And yes, having to it like this also means that doing restores are quite a pain, but that is another problem.
Normally I do error handling in scripts by evaluating $?, but to have proper error handling in here I need to capture the exit value of both mysqldump and gzip. And $? only gives med the exit value of gzip - the least important of the two.
Luckily, and as expected, I'm not the first person to run into this problem, ad by way of googling I found that Bash actually have a built-in way of giving me both exit values - the array $PIPESTATUS. $PIPESTATUS is an array with all the exit values from you last command line. $PIPESTATUS[0] contains the first exit value, $PIPESTATUS[1] the second and so on
You can also get the entire arraysigurdur@ifconfig:~$ true | falsesigurdur@ifconfig:~$ echo ${PIPESTATUS[0]}0sigurdur@ifconfig:~$ true | falsesigurdur@ifconfig:~$ echo ${PIPESTATUS[1]}1
sigurdur@ifconfig:~$ true | false |false |true
sigurdur@ifconfig:~$ echo ${PIPESTATUS[@]}
0 1 1 0A single, non-piped command is considered to be a "pipe of one", thus leaving you with a $PIPESTATUS array with one value. Since $PIPESTATUS is updated after every command line I had to copy the array before extracting the exit values.
So my code ended up like this:
PIPESTATUS have probably been part of Bash since forever, but to me it was new - and it solved my problem. Fun stuff:-)$MYSQLDUMP $MYSQLDUMP_OPTS $DB | gzip -9# We want the exit values of both mysqldump and gzipexitarray=("${PIPESTATUS[@]}")mydumpexitcode=${exitarray[0]}gzipexitcode=${exitarray[1]}