A blog by Gary Bernhardt, Creator & Destroyer of Software

An Aside About Shell Conditionals

21 Nov 2010

The && shell operator is used in two common contexts. First, to chain commands like ; does, but stop on failure. For example:

$ mkdir foo && cd foo && echo 'done!' && cd ..
done!
$ mkdir foo && cd foo && echo 'done!' && cd ..
mkdir: foo: File exists

The directory existed on the second try, so mkdir set $?, the error code, to 1. An error code of 0 is success; non-zero is failure. The && operator saw that $? was non-zero, meaning that the mkdir failed, so it exited.

The second common application of && is within comparisons: you can use it in conditionals as a logical "and" operator. It acts as you'd expect it to act in any other programming language:

$ if [ 1 = 1 ] && true; then echo ok; fi  
ok
$ if [ 1 = 100 ] && true; then echo ok; fi
$ if [ 1 = 1 ] && false; then echo ok; fi

Above, we saw that the && operator continues executing only if the previous command sets $? to 0, the success value. Which means...

In shell conditionals, the true things are 0 and the false things are 1! I know – it's Wrong, but it also makes everything Just Work.

Oh... and one more thing. true, false, and [ are all programs:

$ which true false [
/usr/bin/true
/usr/bin/false
/bin/[

Noodle on that for a while! Which program knows what = means? Why is the ] there when using a conditional at the shell? (Isn't it just a meaningless argument passed to [?)

(Seriously – think about these questions before proceeding.)

...

I'm not going to answer them, but I will show you this:

$ /bin/[ 1 = 1; echo $?
0
$ /bin/[ 1 = 2; echo $?
1

(This post started as an aside in The Tar Pipe that didn't make the cut. See that post for more Unix bits.)