I have a script which quite often fails. It is crucial that the correct exit code is passed on.
This code works as expected:
#!/usr/bin/env bash
function my_function {
echo "Important output"
exit 1
}
function cleanup {
MY_EXIT_CODE=$?
echo "MY_EXIT_CODE: ${MY_EXIT_CODE}"
}
trap cleanup EXIT
my_function
MY_EXIT_CODE
is 1
as expected and running echo $?
after the script gives me 1
as well (as expected)
However, I need to get the complete output of my_function
both to a variable and the console output. In order to do so, as advised in this answer (which seems itself based on this answer) I changed my code into
#!/usr/bin/env bash
function my_function {
echo "Important output"
exit 1
}
function cleanup {
MY_EXIT_CODE=$?
echo "MY_EXIT_CODE: ${MY_EXIT_CODE}"
}
trap cleanup EXIT
exec 5>&1
FF=$(my_function|tee /dev/fd/5)
And now the exit code is wrong. Is it 0
while it should be 1
. I know this is somewhat connected to subshell handling but I couldn't figure out how to solve it.
And now the exit code is wrong. Is it 0 while it should be 1
No, your assumption is wrong. Assuming tee
succeeded, the exit code should be 0. From the posix shell manual:
If the reserved word ! does not precede the pipeline, the exit status shall be the exit status of the last command specified in the pipeline.
The "last command" in a pipeline is the rightmost command. Because in your case tee
exits with 0, the exit status of FF=$(.... | tee)
is zero.
how to solve it.
That depends on the behavior you want to achieve. Usually, in bash you may just set -o pipefail
to always catch errors.