Exception handling in shell scripting?

Solution 1:

There is not really a try/catch in bash (i assume you're using bash), but you can achieve a quite similar behaviour using && or ||.

In this example, you want to run fallback_command if a_command fails (returns a non-zero value):

a_command || fallback_command

And in this example, you want to execute second_command if a_command is successful (returns 0):

a_command && second_command

They can easily be mixed together by using a subshell, for example, the following command will execute a_command, if it succeeds it will then run other_command, but if a_command or other_command fails, fallback_command will be executed:

(a_command && other_command) || fallback_command

Solution 2:

The if/else structure and exit codes can help you fake some of it. This should work in Bash or Bourne (sh).

if foo ; then
else
  e=$?        # return code from if
  if [ "${e}" -eq "1"]; then
    echo "Foo returned exit code 1"
  elif [ "${e}" -gt "1"]; then
    echo "Foo returned BAD exit code ${e}"
  fi
fi

Solution 3:

{
    # command which may fail and give an error 
} || {
   # command which should be run instead of the above failing      command
}

Solution 4:

Here are two simple bashfunctions which enable eventhandling in bash:

You could use it for basic exceptionhandling like this:

onFoo(){
  echo "onFoo() called width arg $1!"
}  

foo(){
  [[ -f /tmp/somefile ]] || throw EXCEPTION_FOO_OCCURED "some arg"
} 

addListener EXCEPTION_FOO_OCCURED onFoo

Exceptionhandling using try/catch blocks is not supported in bash, however, you might wanna try looking at the BANGSH framework which supports it (its a bit like jquery for bash).

However, exceptionhandling without cascading try/catch-blocks is similar to eventhandling, which is possible in almost any language with array-support.

If you want to keep your code nice and tidy (without if/else verbosity), I would recommend to use events.

The suggestion which MatToufoutu recommends (using || and &&) is not recommended for functions, but ok for simple commands. (see BashPitfalls about the risks)