Shell Tips 4: Safe coding by testing exit conditions

February 14, 2011

How testing works — avoiding unnecessary $?’s
People often want to test whether a command has worked or not, which is a good
thing. You often see code that uses the $? variable, which stores the exit code,
the success or failure, of the most recent instruction.

if [ $? -eq 0 ]
echo "it worked"
echo "it failed"

However, this is somewhat back-to-front. The “if” command’s primary use is to
test for the success or failure of a command. To test an abstract, boolean
function, it has to be evaluated and turned into an exit value, which is what the ‘test’
keyword does (and its equivalent, the square brackets). Therefore the code above can be simpified

if dosomething
echo "it worked"
echo "it failed"

4.2 There is an even more compact way of writing this kind of code (and if you are not writing code this way,
you probably should be, especially if it is to be run by root, or to run unattended).

dosomething && echo "it worked"
dosomething || exit 1

The second form — try something, and quit on fail — is the more useful. It is more useful still if, instead of
quitting just quitting, it calls a function that tidies up, deleting temporary files and so on.

dosomething || my_exit_function

4.3 A particularly useful construct, often seen in well-written scripts is

cd /somewhere | exit

Why? Suppose you have code that says

cd /somewhere
rm -r *

…and suppose /somewhere doesn’t exist. Then the “rm” will remove everything from whatever directory
the script was previously in, which might well be the root directory!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: