1 |
#!/bin/bash |
2 |
# |
3 |
# Cases relevant to set -o strict-errexit in OSH. |
4 |
# |
5 |
# Summary: |
6 |
# - errexit is reset to false in ash/bash -- completely ignored! |
7 |
# - local assignment is different than global! The exit code and errexit |
8 |
# behavior are different because the concept of the "last command" is |
9 |
# different. |
10 |
# - ash has copied bash behavior! |
11 |
|
12 |
#### command sub: errexit ignored |
13 |
# This is the bash-specific bug here: |
14 |
# https://blogs.janestreet.com/when-bash-scripts-bite/ |
15 |
# In bash 4.4, inherit_errexit should fix this. |
16 |
set -o errexit |
17 |
echo $(echo one; false; echo two) # bash/ash keep going |
18 |
echo status=$? |
19 |
## STDOUT: |
20 |
one two |
21 |
status=0 |
22 |
## END |
23 |
# dash and mksh: inner shell aborts, but outer one keeps going! |
24 |
## OK dash/mksh STDOUT: |
25 |
one |
26 |
status=0 |
27 |
## END |
28 |
|
29 |
#### command sub: errexit not ignored with strict-errexit |
30 |
set -o errexit |
31 |
set -o strict-errexit || true |
32 |
echo zero |
33 |
echo $(echo one; false; echo two) # bash/ash keep going |
34 |
echo status=$? |
35 |
## STDOUT: |
36 |
zero |
37 |
## END |
38 |
## status: 1 |
39 |
## N-I dash status: 2 |
40 |
## N-I dash stdout-json: "" |
41 |
## N-I mksh stdout-json: "" |
42 |
## N-I ash/bash status: 0 |
43 |
## N-I ash/bash STDOUT: |
44 |
zero |
45 |
one two |
46 |
status=0 |
47 |
## END |
48 |
|
49 |
#### command sub: last command fails but keeps going and exit code is 0 |
50 |
set -o errexit |
51 |
echo $(echo one; false) # we lost the exit code |
52 |
echo status=$? |
53 |
## STDOUT: |
54 |
one |
55 |
status=0 |
56 |
## END |
57 |
|
58 |
#### global assignment with command sub: middle command fails |
59 |
set -o errexit |
60 |
s=$(echo one; false; echo two;) |
61 |
echo "$s" |
62 |
## status: 0 |
63 |
## STDOUT: |
64 |
one |
65 |
two |
66 |
## END |
67 |
# dash and mksh: whole thing aborts! |
68 |
## OK dash/mksh stdout-json: "" |
69 |
## OK dash/mksh status: 1 |
70 |
|
71 |
#### global assignment with command sub: last command fails and it aborts |
72 |
set -o errexit |
73 |
s=$(echo one; false) |
74 |
echo status=$? |
75 |
## stdout-json: "" |
76 |
## status: 1 |
77 |
|
78 |
#### local: middle command fails and keeps going |
79 |
set -o errexit |
80 |
f() { |
81 |
echo good |
82 |
local x=$(echo one; false; echo two) |
83 |
echo status=$? |
84 |
echo $x |
85 |
} |
86 |
f |
87 |
## STDOUT: |
88 |
good |
89 |
status=0 |
90 |
one two |
91 |
## END |
92 |
# for dash and mksh, the INNER shell aborts, but the outer one keeps going! |
93 |
## OK dash/mksh STDOUT: |
94 |
good |
95 |
status=0 |
96 |
one |
97 |
## END |
98 |
|
99 |
#### local: last command fails and also keeps going |
100 |
set -o errexit |
101 |
f() { |
102 |
echo good |
103 |
local x=$(echo one; false) |
104 |
echo status=$? |
105 |
echo $x |
106 |
} |
107 |
f |
108 |
## STDOUT: |
109 |
good |
110 |
status=0 |
111 |
one |
112 |
## END |
113 |
|
114 |
#### local and strict-errexit |
115 |
# I've run into this problem a lot. |
116 |
set -o errexit |
117 |
set -o strict-errexit || true # ignore error |
118 |
f() { |
119 |
echo good |
120 |
local x=$(echo one; false; echo two) |
121 |
echo status=$? |
122 |
echo $x |
123 |
} |
124 |
f |
125 |
## status: 1 |
126 |
## STDOUT: |
127 |
good |
128 |
## END |
129 |
## N-I bash/ash status: 0 |
130 |
## N-I bash/ash STDOUT: |
131 |
good |
132 |
status=0 |
133 |
one two |
134 |
## END |
135 |
## N-I dash status: 2 |
136 |
## N-I dash stdout-json: "" |
137 |
## N-I mksh status: 1 |
138 |
## N-I mksh stdout-json: "" |
139 |
|
140 |
#### global assignment when last status is failure |
141 |
# this is a bug I introduced |
142 |
set -o errexit |
143 |
[ -n "${BUILDDIR+x}" ] && _BUILDDIR=$BUILDDIR |
144 |
BUILDDIR=${_BUILDDIR-$BUILDDIR} |
145 |
echo status=$? |
146 |
## STDOUT: |
147 |
status=0 |
148 |
## END |
149 |
|
150 |
#### global assignment when last status is failure |
151 |
# this is a bug I introduced |
152 |
set -o errexit |
153 |
x=$(false) || true # from abuild |
154 |
[ -n "$APORTSDIR" ] && true |
155 |
BUILDDIR=${_BUILDDIR-$BUILDDIR} |
156 |
echo status=$? |
157 |
## STDOUT: |
158 |
status=0 |
159 |
## END |