Let's say I code something like:
if [ ${?} -ne 0 ]; then
exit ${?}
Would this work properly? Is this correct "syntax-wise"?
Let's say I code something like:
if [ ${?} -ne 0 ]; then
exit ${?}
Would this work properly? Is this correct "syntax-wise"?
The [
command in your if
statement will set $?
after it checks. You'll need to save the original exit status before testing.
some_command
es=$?
if [ "$es" -ne 0 ]; then
exit "$es"
fi
The syntax is correct, but $?
is reset by the [ ... ]
command in the if
statement. By definition, if the if
block is entered then the [ ... ]
test must have been successful, and $?
is guaranteed to be 0
.
You'll need to save it in a variable.
result=$?
if ((result != 0)); then
exit "$result"
fi
Alternately, it's more idiomatic to test the result of a command directly rather than testing $?
. If you do so then you don't have the problem of $?
changing.
if command; then
echo success
else
exit # `exit` is equivalent to `exit $?`
fi
If you don't care about success then you can use ||
:
command || exit
If you want to exit on error and preserve the EXIT code of the command, you can enable the errexit
option:
set -e
set -o errexit
See: help set | grep -F -- -e
-e Exit immediately if a command exits with a non-zero status.
errexit same as -e
Alternatively you can trap
the ERR
signal and use this to exit with the return code of the error.
This will save you from dealing with the -e
option consequences.
#!/usr/bin/env bash
err_handler() {
set -- $?
printf 'The error handler caught code #%d\n' "$1" >&2
exit "$1"
}
trap 'err_handler' ERR
create_error() {
[ $# -ne 1 ] && return 0
printf 'Create error #%d\n' "$1"
return "$1"
}
create_error "$@"
Testing with different errors:
for e in 1 0 2; do ./a.sh "$e" ;echo $?; done
Create error #1
The error handler caught code #1
1
Create error #0
0
Create error #2
The error handler caught code #2
2