Bash – How to get the output and exit value of a subshell when using “bash -e”

bash

Consider the following code

outer-scope.sh

#!/bin/bash
set -e
source inner-scope.sh
echo $(inner)
echo "I thought I would've died :("

inner-scope.sh

#!/bin/bash
function inner() { echo "winner"; return 1; }

I'm trying to get outer-scope.sh to exit when a call to inner() fails. Since $() invokes a sub-shell, this doesn't happen.

How else do I get the output of a function while preserving the fact that the function may exit with a non-zero exit code?

Best Answer

$() preserves the exit status; you just have to use it in a statement that has no status of its own, such as an assignment.

output=$(inner)

After this, $? would contain the exit status of inner, and you can use all sorts of checks for it:

output=$(inner) || exit $?
echo $output

Or:

if ! output=$(inner); then
    exit $?
fi
echo $output

Or:

if output=$(inner); then
    echo $output
else
    exit $?
fi

(Note: A bare exit without arguments is equivalent to exit $? – that is, it exits with the last command's exit status. I used the second form only for clarity.)


Also, for the record: source is completely unrelated in this case. You can just define inner() in the outer-scope.sh file, with the same results.

Related Question