Exception handling for a particular exit_code in shell scripting?

Viewed 108

i understood that

a_command || fallback_command

It will catch any non zero exit_code from command_a (i.e when command_a fails) and will run fallback_commad. How to achieve this for some particular codes? How to make it work like when a_command throws 255 only then run fallback_command ?

I tried to do something like

a_command
VAR=$?
if [ $VAR==255 ]
then
    fallback_command
    exit 0
fi

But this will not suppress the non zero errors thrown by command_a. I want to suppress the non zero exit_codes.

6 Answers

IMHO case is perfect for this

a_command
VAR=$?
case $VAR in
    255) fallback_command ;;
    123) fallback_command2;;
    ...) ...   ;;
      0) exit 0;;
esac

You have one mistake in your code. [ $VAR==255 ] will always be true, because it is the same as this:

[ string ]
Returns true if string is not empty.

If you want to compare numbers, use -eq:

if [ $VAR -eq 255 ]

Similarly, to test equality of strings you would use:

if [ $VAR = 255 ]

In your case you want to use -eq.

This page can help: https://www.computerhope.com/unix/bash/test.htm

As simple as this with maintaining the inline boolean or ||:

a_command || [ $? -ne 255 ] || fallback_command

Testing the implementation:

#!/usr/bin/env bash

a_command_success(){ echo 'running a_command_success';}
a_command_failing_42(){ echo 'running a_command_failing_42'; return 42;}
a_command_failing_255(){ echo 'running a_command_failing_255'; return 255;}

fallback_command(){ echo 'running fallback_command';}

for a_command in a_command_success a_command_failing_255 a_command_failing_42
do "$a_command" || [ $? -ne 255 ] || fallback_command; done

Output of test:

running a_command_success
running a_command_failing_255
running fallback_command
running a_command_failing_42

Going further with a fall_back caller utility command:

# When return code equals argument 1, execute command and arguments 2+
# Example:
# a_command || falllback_rc 255 fallback_command arg1 arg2 ... argn
fallback_rc(){ [ "$?" -eq "$1" ]&&{ shift;"$@";}}

You can just do with an if instruction:

command_a

if test $? = 255

then

   fallback_command

fi

One one line :

command_a ; if test $? = 255 ; then fallback_command ; fi

Your code will always execute the fallback_command. The reason is that test x always succeeds, if x is not empty. As an example, assume that VAR equals 100, so you basically do a test 100==255, and since the string 100==255 is not empty (it has a length of 8 characters), the condition suceeds.

You could do something like:

if (( VAR > 127 ))
then
  # There was a problem starting the program
  ....
elif (( VAR == 72 || VAR >118 ))
then
  # Deal with exit codes 72 and 119 up to 127
  .....
elif (( VAR > 0 ))
  # Deal with all other non-zero exit codes
  ....
fi

Well after trying a bit i found out a way

a_command || export ECODE="$?"    # Here non zero exit codes are suppressed.

if [ "$ECODE" -eq 255 ]

then
    fallback_command
fi
Related