2

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.

1
  • 1
    "==" works with the c language's if instruction. In bash, [ and ] correspond to the test command which doesn't understands ==. It only recognises -eq and = Commented Jun 26, 2020 at 9:30

7 Answers 7

3

IMHO case is perfect for this

a_command
VAR=$?
case $VAR in
    255) fallback_command ;;
    123) fallback_command2;;
    ...) ...   ;;
      0) exit 0;;
esac
Sign up to request clarification or add additional context in comments.

1 Comment

The problem lies in the later part of the question. In the first line when a_command runs and if exits with a non-zero exit-code. My docker container exits with the code that a_command returns. It doesnt even come to line number 2. So some how i have to suppress the error from line 1.
1

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;"$@";}}

Comments

1

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

Comments

0

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

Comments

0

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

Comments

0

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

Comments

0

To play nice with set -e and traps:

set -e

trap cleanup ERR

cleanup () {
    echo cleaning up
}

a_command && rc=0 || rc=$?
case $rc in
    0)
        # no error handling needed
        ;;

    255)
        # handle error code 255
        fallback_command
        ;;
    254)
        # handle error code 254
        another_fallback_command
        ;;
    *)
        # unhandled error code; subshell used so we can trigger `set -e`
        # and any associated traps without exiting directly
        (exit "$rc")
        ;;
esac

If no traps on ERR are used, we can just exit directly like set -e normally would:

set -e

a_command && rc=0 || rc=$?
case $rc in
    0)
        # no error handling needed
        ;;

    255)
        # handle error code 255
        fallback_command
        ;;
    254)
        # handle error code 254
        another_fallback_command
        ;;
    *)
        # unhandled error code; exit like `set -e` normally would
        exit "$rc"
        ;;
esac

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.