I'm looking for exception handling mechanism in shell script. Is there any try,catch equivalent mechanism in shell script ?
-
Related: [Could someone explain this try/catch alternative in bash?](http://stackoverflow.com/q/14964529/320399) – blong Apr 11 '14 at 12:54
-
Related: [Raise error in a Bash script](https://stackoverflow.com/a/50265513/6862601) – codeforester Feb 04 '19 at 22:32
5 Answers
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

- 17,513
- 7
- 56
- 60
-
15Bonus: if you want "finally" like behavior, use the no-op (: in bash) like this: `(a_command || : )` and the next line will run as if no error happened in `a_command`. – B T Feb 18 '14 at 05:43
-
Not really because the semantics of finally is that it runs regardless of the exception state. – F. P. Freely Jul 16 '20 at 18:46
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

- 2,059
- 15
- 7
-
1`if foo ; then else` can be simplified to `if ! foo ; then`, +1 anyway. – jlliagre Aug 07 '11 at 10:24
-
3@jiliagre That does not work. "! foo" inverts $? from 0 to 1 and !0 to 0. – brightlancer Aug 07 '11 at 16:38
-
can this part: if [ "${e}" -eq "1"]; then echo "Foo returned exit code 1" elif [ "${e}" -gt "1"]; then echo "Foo returned BAD exit code ${e}" be simplified to: if [ "${e}" -ge "1" ]; then echo "Foo returned BAD exit code ${e}" ? – kouichi Feb 28 '21 at 01:36
{
# command which may fail and give an error
} || {
# command which should be run instead of the above failing command
}

- 5,987
- 8
- 76
- 112

- 221
- 2
- 5
-
7It would probably be `better` if you explained to the one asking the question, the pseudo-code you post rather than just a block of cryptic code that they may not understand. If a child cannot understand it, it is not a good answer. – Yokai Mar 20 '17 at 04:01
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)

- 1,764
- 16
- 13
Use following to handle error properly where error_exit is function that accepts one argument. In case if argument is not passed then it will throw unknown error with LineNo where actually error is happening. Please experiment before actually uses for production -
#!/bin/bash
PROGNAME=$(basename $0)
error_exit()
{
echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2
exit 1
}
echo "Example of error with line number and message"
error_exit "$LINENO: An error has occurred."

- 3,815
- 2
- 26
- 26