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]}
Cheers for that, Sigurd!
ReplyDeleteOh, PIPESTATUS, where have you been all this time.
ReplyDeleteAnother nice pipe-related thing is Pipeviewer. Lars Strand blogged about it a while back - see http://blog.larsstrand.org/2011/12/tip-pipe-viewer.html for the nice details.
ReplyDeleteThank you very much.After spending more than 1 hour on google I got your post. Helped me a lot with my time.some of my code snippet
ReplyDelete$MYSQLDUMP $SRC_DB | $MYSQL $DEST_DB >> $ERRORLOG 2>&1
exitstatus=("${PIPESTATUS[@]}")
echo "dump status-->" ${exitstatus[0]}
echo "restore status-->" ${exitstatus[1]}
dumperror=`expr ${exitstatus[0]} + ${exitstatus[1]}`
echo "dump error --> $dumperror"
if [ "$dumperror" = "0" ]; then
echo "$TODAYS_DATE DB copy executed successfully" >> $LOGFILE
else
echo "$TODAYS_DATE DB copy Failed exiting process" >> $LOGFILE
exit 1
fi