Coding Range

Bash Pipe Status

April 19th, 2012

I had some fun when scripting today, trying to figure out why $? wasn’t returning 0 when the command clearly failed. Before I get to the problem, a quick overview of $?:

$ true
$ echo $?
0
$ false
$ echo $?
1
$ true | false
$ echo $?
1
$ false | true
$ echo $?
0

$? only returns the return value of the last command to run. Unfortunately, my problem was that I was running

failingcommand | tee logfile

Here’s the result:

$ true | tee log.txt
$ echo $?
0
$ false | tee log.txt
$ echo $?
0

False positives for all! Fortunately, there’s ${PIPESTATUS}. PIPESTATUS is an array of all the return values of the previous line.

$ true | false
$ echo ${PIPESTATUS[0]}
0
$ false | true
$ echo ${PIPESTATUS[0]}
1
$ true | tee log.txt
$ echo ${PIPESTATUS[0]}
0
$ false | tee log.txt
$ echo ${PIPESTATUS[0]}
1

That looks a little better.