Search code examples
bashgitlab-ciexit-code

Bash running multiple commands, until one fails while capturing last exit code


My question is partially answered here: gitlab ci scripts during which $? is allowed to be non-zero

In principle, I want to achieve the following in bash:

// assume both functions return truthy values and the 2nd doesn't run if 1st fails

$success = test1() && test2();

someOtherStuff();

exit($success);

GitLab CI scripts terminate immediately when any simple command fails (possibly due to set -e, IDK for sure).

The nearest (and taking that link into consideration):

CODE=0
if test1 && test2; then
    CODE=1
fi

someOtherStuff

exit $CODE

Is there any better way? In particular, I'd like to get the real $CODE not a fake one.


Solution

  • As I understand it, you're asking how to run a series of commands until one fails, and store the exit status of the failing command for future reference, in a manner which is robust against side effects of set -e.

    Using test1, test2 and test3 as our commands:

    #!/usr/bin/env bash
    
    test1() { return 0; }
    test2() { return 2; }
    test3() { echo "THIS SHOULD NOT BE RUN"; }
    someOtherStuff() { echo "This should be run; current value of retval is $retval"; }
    
    retval=0
    test1 && test2 && test3 || retval=$?
    someOtherStuff ||: "ignoring a failure here"
    exit "$retval"
    

    || retval=$? makes test1 && test2 && test3 a checked expression, thus immune to set -e.

    : is a synonym for true, with a history of conventional use as a placeholder.


    Running the above, we have the following output:

    This should be run; current value of retval is 2
    

    ...and the exit status of the script is indeed 2.