1 |
# |
2 |
# Usage: |
3 |
# ./errexit.test.sh <function name> |
4 |
|
5 |
#### errexit aborts early |
6 |
set -o errexit |
7 |
false |
8 |
echo done |
9 |
## stdout-json: "" |
10 |
## status: 1 |
11 |
|
12 |
#### errexit for nonexistent command |
13 |
set -o errexit |
14 |
nonexistent__ZZ |
15 |
echo done |
16 |
## stdout-json: "" |
17 |
## status: 127 |
18 |
|
19 |
#### errexit aborts early on pipeline |
20 |
set -o errexit |
21 |
echo hi | grep nonexistent |
22 |
echo two |
23 |
## stdout-json: "" |
24 |
## status: 1 |
25 |
|
26 |
#### errexit with { } |
27 |
# This aborts because it's not part of an if statement. |
28 |
set -o errexit |
29 |
{ echo one; false; echo two; } |
30 |
## stdout: one |
31 |
## status: 1 |
32 |
|
33 |
#### errexit with if and { } |
34 |
set -o errexit |
35 |
if { echo one; false; echo two; }; then |
36 |
echo three |
37 |
fi |
38 |
echo four |
39 |
## status: 0 |
40 |
## STDOUT: |
41 |
one |
42 |
two |
43 |
three |
44 |
four |
45 |
## END |
46 |
|
47 |
#### errexit with || |
48 |
set -o errexit |
49 |
echo hi | grep nonexistent || echo ok |
50 |
## stdout: ok |
51 |
## status: 0 |
52 |
|
53 |
#### errexit with && |
54 |
set -o errexit |
55 |
echo ok && echo hi | grep nonexistent |
56 |
## stdout: ok |
57 |
## status: 1 |
58 |
|
59 |
#### errexit test && -- from gen-module-init |
60 |
set -o errexit |
61 |
test "$mod" = readline && echo "#endif" |
62 |
echo status=$? |
63 |
## stdout: status=1 |
64 |
|
65 |
#### errexit test && and fail |
66 |
set -o errexit |
67 |
test -n X && false |
68 |
echo status=$? |
69 |
## stdout-json: "" |
70 |
## status: 1 |
71 |
|
72 |
#### errexit and loop |
73 |
set -o errexit |
74 |
for x in 1 2 3; do |
75 |
test $x = 2 && echo "hi $x" |
76 |
done |
77 |
## stdout: hi 2 |
78 |
## status: 1 |
79 |
|
80 |
#### errexit and brace group { } |
81 |
set -o errexit |
82 |
{ test no = yes && echo hi; } |
83 |
echo status=$? |
84 |
## stdout: status=1 |
85 |
|
86 |
#### errexit and time { } |
87 |
set -o errexit |
88 |
time false |
89 |
echo status=$? |
90 |
## status: 1 |
91 |
|
92 |
#### errexit with ! |
93 |
set -o errexit |
94 |
echo one |
95 |
! true |
96 |
echo two |
97 |
! false |
98 |
echo three |
99 |
## STDOUT: |
100 |
one |
101 |
two |
102 |
three |
103 |
## END |
104 |
|
105 |
#### errexit with ! and ; |
106 |
# AST has extra Sentence nodes; there was a REGRESSION here. |
107 |
set -o errexit; echo one; ! true; echo two; ! false; echo three |
108 |
## STDOUT: |
109 |
one |
110 |
two |
111 |
three |
112 |
## END |
113 |
|
114 |
#### errexit with while/until |
115 |
set -o errexit |
116 |
while false; do |
117 |
echo ok |
118 |
done |
119 |
until false; do |
120 |
echo ok # do this once then exit loop |
121 |
break |
122 |
done |
123 |
## stdout: ok |
124 |
## status: 0 |
125 |
|
126 |
#### errexit with (( )) |
127 |
# from http://mywiki.wooledge.org/BashFAQ/105, this changed between verisons. |
128 |
# ash says that 'i++' is not found, but it doesn't exit. I guess this is the |
129 |
# subshell problem? |
130 |
set -o errexit |
131 |
i=0 |
132 |
(( i++ )) |
133 |
echo done |
134 |
## stdout-json: "" |
135 |
## status: 1 |
136 |
## N-I dash/ash status: 127 |
137 |
## N-I dash/ash stdout-json: "" |
138 |
|
139 |
#### errexit with subshell |
140 |
set -o errexit |
141 |
( echo one; false; echo two; ) |
142 |
echo three |
143 |
## status: 1 |
144 |
## STDOUT: |
145 |
one |
146 |
## END |
147 |
|
148 |
#### set -o errexit while it's being ignored (moot with strict_errexit) |
149 |
set -o errexit |
150 |
# osh aborts early here |
151 |
if { echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4; }; then |
152 |
echo 5; |
153 |
fi |
154 |
echo 6 |
155 |
false # this is the one that makes shells fail |
156 |
echo 7 |
157 |
## status: 1 |
158 |
## STDOUT: |
159 |
1 |
160 |
2 |
161 |
3 |
162 |
4 |
163 |
5 |
164 |
6 |
165 |
## END |
166 |
|
167 |
#### set +o errexit while it's being ignored (moot with strict_errexit) |
168 |
set -o errexit |
169 |
if { echo 1; false; echo 2; set +o errexit; echo 3; false; echo 4; }; then |
170 |
echo 5; |
171 |
fi |
172 |
echo 6 |
173 |
false # does NOT fail, because we restored it. |
174 |
echo 7 |
175 |
## STDOUT: |
176 |
1 |
177 |
2 |
178 |
3 |
179 |
4 |
180 |
5 |
181 |
6 |
182 |
7 |
183 |
## END |
184 |
|
185 |
#### set +o errexit with 2 levels of ignored |
186 |
set -o errexit |
187 |
if { echo 1; ! set +o errexit; echo 2; }; then |
188 |
echo 3 |
189 |
fi |
190 |
echo 6 |
191 |
false |
192 |
echo 7 |
193 |
|
194 |
## STDOUT: |
195 |
1 |
196 |
2 |
197 |
3 |
198 |
6 |
199 |
7 |
200 |
## END |
201 |
|
202 |
#### setting errexit in a subshell works but doesn't affect parent shell |
203 |
( echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4; ) |
204 |
echo 5 |
205 |
false |
206 |
echo 6 |
207 |
## STDOUT: |
208 |
1 |
209 |
2 |
210 |
3 |
211 |
5 |
212 |
6 |
213 |
## END |
214 |
|
215 |
#### set errexit while it's ignored in a subshell (moot with strict_errexit) |
216 |
set -o errexit |
217 |
if ( echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4 ); then |
218 |
echo 5; |
219 |
fi |
220 |
echo 6 # This is executed because the subshell just returns false |
221 |
false |
222 |
echo 7 |
223 |
## status: 1 |
224 |
## STDOUT: |
225 |
1 |
226 |
2 |
227 |
3 |
228 |
4 |
229 |
5 |
230 |
6 |
231 |
## END |
232 |
|
233 |
#### shopt -s strict:all || true while errexit is on |
234 |
set -o errexit |
235 |
shopt -s strict:all || true |
236 |
echo one |
237 |
false # fail |
238 |
echo two |
239 |
## status: 1 |
240 |
## STDOUT: |
241 |
one |
242 |
## END |
243 |
|
244 |
#### errexit double guard |
245 |
# OSH bug fix. ErrExit needs a counter, not a boolean. |
246 |
set -o errexit |
247 |
if { ! false; false; true; } then |
248 |
echo true |
249 |
fi |
250 |
false |
251 |
echo done |
252 |
## status: 1 |
253 |
## STDOUT: |
254 |
true |
255 |
## END |
256 |
|
257 |
#### background processes respect errexit |
258 |
set -o errexit |
259 |
{ echo one; false; echo two; exit 42; } & |
260 |
wait $! |
261 |
## status: 1 |
262 |
## STDOUT: |
263 |
one |
264 |
## END |
265 |
|
266 |
#### pipeline process respects errexit |
267 |
set -o errexit |
268 |
# It is respected here. |
269 |
{ echo one; false; echo two; } | cat |
270 |
|
271 |
# Also respected here. |
272 |
{ echo three; echo four; } | while read line; do |
273 |
echo "[$line]" |
274 |
false |
275 |
done |
276 |
echo four |
277 |
## status: 1 |
278 |
## STDOUT: |
279 |
one |
280 |
[three] |
281 |
## END |
282 |
|
283 |
#### compound command |
284 |
# case from |
285 |
# https://lists.gnu.org/archive/html/bug-bash/2020-05/msg00066.html |
286 |
|
287 |
set -o errexit |
288 |
|
289 |
{ cat ; } < not_exist.txt |
290 |
|
291 |
echo status=$? |
292 |
echo 'should not get here' |
293 |
## status: 1 |
294 |
## stdout-json: "" |
295 |
## BUG dash/bash/ash status: 0 |
296 |
## BUG bash/ash STDOUT: |
297 |
status=1 |
298 |
should not get here |
299 |
## END |
300 |
## BUG dash STDOUT: |
301 |
status=2 |
302 |
should not get here |
303 |
## END |
304 |
|
305 |
#### while loop |
306 |
# case from |
307 |
# https://lists.gnu.org/archive/html/bug-bash/2020-05/msg00066.html |
308 |
|
309 |
set -o errexit |
310 |
|
311 |
while read line; do |
312 |
echo $line |
313 |
done < not_exist.txt |
314 |
|
315 |
echo status=$? |
316 |
echo 'should not get here' |
317 |
## status: 1 |
318 |
## stdout-json: "" |
319 |
## BUG dash/bash/ash status: 0 |
320 |
## BUG bash/ash STDOUT: |
321 |
status=1 |
322 |
should not get here |
323 |
## END |
324 |
## BUG dash STDOUT: |
325 |
status=2 |
326 |
should not get here |
327 |
## END |
328 |
|
329 |
#### set -e enabled in function (regression) |
330 |
foo() { |
331 |
set -e |
332 |
false |
333 |
echo "should be executed" |
334 |
} |
335 |
#foo && true |
336 |
#foo || true |
337 |
|
338 |
if foo; then |
339 |
true |
340 |
fi |
341 |
|
342 |
echo "should be executed" |
343 |
## STDOUT: |
344 |
should be executed |
345 |
should be executed |
346 |
## END |
347 |
|
348 |
#### set -e in function #2 |
349 |
foo() { |
350 |
set -e |
351 |
false |
352 |
echo "should be executed" |
353 |
} |
354 |
! foo |
355 |
|
356 |
echo "should be executed" |
357 |
## BUG bash stdout-json: "" |
358 |
## BUG bash status: 1 |
359 |
## STDOUT: |
360 |
should be executed |
361 |
should be executed |
362 |
## END |
363 |
|
364 |
|
365 |
#### Command sub exit code is lost |
366 |
echo ft $(false) $(true) |
367 |
echo status=$? |
368 |
|
369 |
set -o errexit |
370 |
shopt -s inherit_errexit || true |
371 |
|
372 |
# This changes it |
373 |
#shopt -s command_sub_errexit || true |
374 |
|
375 |
echo f $(date %x) |
376 |
echo status=$? |
377 |
|
378 |
# compare with |
379 |
# x=$(date %x) # FAILS |
380 |
# local x=$(date %x) # does NOT fail |
381 |
|
382 |
echo ft $(false) $(true) |
383 |
echo status=$? |
384 |
|
385 |
## STDOUT: |
386 |
ft |
387 |
status=0 |
388 |
f |
389 |
status=0 |
390 |
ft |
391 |
status=0 |
392 |
## END |
393 |
|