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 versions.
|
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 |
|