I have default bash v4.4.12
set up on Debian:
$ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
I prefer to use these options in my scripts:
set -o pipefail
set -o errexit
set -o nounset
It make stop a script on non-zero result in pipe-commands (pipefail
), execute exit (errexit
), and validate unset variables (nounset
).
I have test script:
set -o pipefail
set -o errexit
set -o nounset
set -o xtrace
return_1() { return 22; }
test_1 () {
return_1;
echo 'after';
}
success_1() {
echo success
}
if [ "${1:-}" == 1 ]; then
# make "return 1" in the root level
return_1
fi
if [ "${1:-}" == 2 ]; then
# run test_1, we will get "return 1" within a function
test_1
fi
if [ "${1:-}" == 3 ]; then
# run test_1 and success_1 in chain
# success_1 MUST NOT be ran because test_1 makes non-zero status
# in fact, success_1 will be ran =(
test_1 && success_1
fi
Testing.
$ bash /test.sh 1; echo "status: ${?}"
+ '[' 1 == 1 ']'
+ return_1
+ return 22
status: 22
Works as expected.
$ bash /test.sh 2; echo "status: ${?}"
+ '[' 2 == 1 ']'
+ '[' 2 == 2 ']'
+ test_1
+ return_1
+ return 22
status: 22
Everything is right. The line "echo 'after';" haven't called.
$ bash /test.sh 3; echo "status: ${?}"
+ '[' 3 == 1 ']'
+ '[' 3 == 2 ']'
+ '[' 3 == 3 ']'
+ test_1
+ return_1
+ return 22
+ echo after
after
+ success_1
+ echo success
success
status: 0
Completely NOT right. :( 1. The line "echo 'after';" have called. 2. The function "success_1" have called as well.
Really, what's going on in this case?
UPD Manual refferences.