View
@@ -0,0 +1,159 @@
#!/bin/bash
#
# Cases relevant to set -o strict-errexit in OSH.
#
# Summary:
# - errexit is reset to false in ash/bash -- completely ignored!
# - local assignment is different than global! The exit code and errexit
# behavior are different because the concept of the "last command" is
# different.
# - ash has copied bash behavior!
### command sub: errexit ignored
# This is the bash-specific bug here:
# https://blogs.janestreet.com/when-bash-scripts-bite/
# In bash 4.4, inherit_errexit should fix this.
set -o errexit
echo $(echo one; false; echo two) # bash/ash keep going
echo status=$?
## STDOUT:
one two
status=0
## END
# dash and mksh: inner shell aborts, but outer one keeps going!
## OK dash/mksh STDOUT:
one
status=0
## END
### command sub: errexit not ignored with strict-errexit
set -o errexit
set -o strict-errexit || true
echo zero
echo $(echo one; false; echo two) # bash/ash keep going
echo status=$?
## STDOUT:
zero
## END
## status: 1
## N-I dash status: 2
## N-I dash stdout-json: ""
## N-I mksh stdout-json: ""
## N-I ash/bash status: 0
## N-I ash/bash STDOUT:
zero
one two
status=0
## END
### command sub: last command fails but keeps going and exit code is 0
set -o errexit
echo $(echo one; false) # we lost the exit code
echo status=$?
## STDOUT:
one
status=0
## END
### global assignment with command sub: middle command fails
set -o errexit
s=$(echo one; false; echo two;)
echo "$s"
## status: 0
## STDOUT:
one
two
## END
# dash and mksh: whole thing aborts!
## OK dash/mksh stdout-json: ""
## OK dash/mksh status: 1
### global assignment with command sub: last command fails and it aborts
set -o errexit
s=$(echo one; false)
echo status=$?
## stdout-json: ""
## status: 1
### local: middle command fails and keeps going
set -o errexit
f() {
echo good
local x=$(echo one; false; echo two)
echo status=$?
echo $x
}
f
## STDOUT:
good
status=0
one two
## END
# for dash and mksh, the INNER shell aborts, but the outer one keeps going!
## OK dash/mksh STDOUT:
good
status=0
one
## END
### local: last command fails and also keeps going
set -o errexit
f() {
echo good
local x=$(echo one; false)
echo status=$?
echo $x
}
f
## STDOUT:
good
status=0
one
## END
### local and strict-errexit
# I've run into this problem a lot.
set -o errexit
set -o strict-errexit || true # ignore error
f() {
echo good
local x=$(echo one; false; echo two)
echo status=$?
echo $x
}
f
# status: 1
## STDOUT:
good
## END
## N-I bash/ash status: 0
## N-I bash/ash STDOUT:
good
status=0
one two
## END
## N-I dash status: 2
## N-I dash stdout-json: ""
## N-I mksh status: 1
## N-I mksh stdout-json: ""
### global assignment when last status is failure
# this is a bug I introduced
set -o errexit
[ -n "${BUILDDIR+x}" ] && _BUILDDIR=$BUILDDIR
BUILDDIR=${_BUILDDIR-$BUILDDIR}
echo status=$?
## STDOUT:
status=0
## END
### global assignment when last status is failure
# this is a bug I introduced
set -o errexit
x=$(false) || true # from abuild
[ -n "$APORTSDIR" ] && true
BUILDDIR=${_BUILDDIR-$BUILDDIR}
echo status=$?
## STDOUT:
status=0
## END
View
@@ -37,8 +37,13 @@ if { echo one; false; echo two; }; then
echo three
fi
echo four
# stdout-json: "one\ntwo\nthree\nfour\n"
# status: 0
## status: 0
## STDOUT:
one
two
three
four
## END
### errexit with ||
set -o errexit
@@ -92,14 +97,20 @@ echo one
echo two
! false
echo three
# stdout-json: "one\ntwo\nthree\n"
# status: 0
## STDOUT:
one
two
three
## END
### errexit with ! and ;
# AST has extra Sentence nodes; there was a REGRESSION here.
set -o errexit; echo one; ! true; echo two; ! false; echo three
# stdout-json: "one\ntwo\nthree\n"
# status: 0
## STDOUT:
one
two
three
## END
### errexit with while/until
set -o errexit
@@ -134,32 +145,6 @@ set -o errexit
# stdout: one
# status: 1
### errexit with command sub
# This is the bash-specific bug here:
# https://blogs.janestreet.com/when-bash-scripts-bite/
set -o errexit
s=$(echo one; false; echo two;)
echo "$s"
# stdout-json: ""
# status: 1
# BUG ash/bash status: 0
# BUG ash/bash stdout-json: "one\ntwo\n"
### errexit with local
# I've run into this problem a lot.
# https://blogs.janestreet.com/when-bash-scripts-bite/
set -o errexit
f() {
echo good
local x=$(echo bad; false)
echo $x
}
f
# stdout-json: "good\n"
# status: 1
# BUG bash/dash/mksh/ash stdout-json: "good\nbad\n"
# BUG bash/dash/mksh/ash status: 0
### setting errexit while it's being ignored
# ignored and then set again
set -o errexit
@@ -170,17 +155,32 @@ fi
echo 6
false # this is the one that makes other shells fail
echo 7
# status: 1
# stdout-json: "1\n2\n"
# OK dash/bash/mksh/ash stdout-json: "1\n2\n3\n4\n5\n6\n"
## status: 1
## STDOUT:
1
2
## END
## OK dash/bash/mksh/ash STDOUT:
1
2
3
4
5
6
## END
### setting errexit in a subshell works but doesn't affect parent shell
( echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4; )
echo 5
false
echo 6
# stdout-json: "1\n2\n3\n5\n6\n"
# status: 0
## STDOUT:
1
2
3
5
6
## END
### setting errexit while it's being ignored in a subshell
set -o errexit
@@ -190,9 +190,19 @@ fi
echo 6 # This is executed because the subshell just returns false
false
echo 7
# status: 1
# stdout-json: "1\n2\n6\n"
# OK dash/bash/mksh/ash stdout-json: "1\n2\n3\n4\n5\n6\n"
## status: 1
## STDOUT:
1
2
6
## OK dash/bash/mksh/ash STDOUT:
1
2
3
4
5
6
## END
### errexit double quard
# OSH bug fix. ErrExit needs a counter, not a boolean.
@@ -202,5 +212,7 @@ if { ! false; false; true; } then
fi
false
echo done
# status: 1
# stdout-json: "true\n"
## status: 1
## STDOUT:
true
## END
View
@@ -438,6 +438,11 @@ errexit() {
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH "$@"
}
errexit-strict() {
sh-spec spec/errexit-strict.test.sh \
${REF_SHELLS[@]} $BUSYBOX_ASH $OSH "$@"
}
#
# Non-POSIX extensions: arrays, brace expansion, [[, ((, etc.
#