Friday, January 12, 2007

BASH Hacks: Error Handling

The reason we use bash in the first place is to execute a lot of external programs in a script. Alot of times however we'll want the script to act differently if one of our commands fails, and unfortunately the standard behavior of the script is to keep chugging along in the face of errors. So we will want to implement error handling in our script to catch and report errors to the end user, and also to stop our script, or change actions if any of the external commands fail in their execution. For alot of *nix programs, the standard behavior is to output nothing unless the command fails, and to handle this type of output is very easy:


#!/bin/bash

if /path/to/command -options
then

#command has failed, actions here

else

#command has completed without errors

fi


In this case the command is executed in an if statement, and if there is any value outputted from the command at all then we assume it has failed. This is the simplest case. If the program is more complicated, and outputs different types of output for success and error, then you will have to trap the output of the command for analysis. There are many ways to do this . . . here I will discuss two:

The first way to do it is to redirect the output of the command into a file and then use cat to read the file:


/path/to/command --options > .file.txt

if cat .file.txt | grep <Pattern>
then

#has failed

else

#has passed

fi


The second way to do it is to trap the output in a variable:


VAR=$(/path/to/command --options)

if echo "$VAR" | grep <Pattern>
then

#has failed

else

#has passed

fi


To match the pattern you will have to examine the error output of the specific command and create a regex for it . . . for example the subversion client program starts its error output with "svn:" so . . . :


if echo "$VAR" | grep ^svn\:


Sometimes you'll want to look for other things aside from error messages in the chatter, so always read your output and then form your pattern to match the specific program.

Enjoy!

2 comments:

Faris said...

Thank you for this helpful post!

stib said...

you can also send the stderr to stdout, and use grep or sed to catch errors without having to write a file. eg:
success=$(foobar --option 2>&1|grep [errormessage])