1 |
#!/usr/bin/env bash |
2 |
# |
3 |
# Usage: |
4 |
# ./errexit.test.sh <function name> |
5 |
|
6 |
### errexit aborts early |
7 |
set -o errexit |
8 |
false |
9 |
echo done |
10 |
# stdout-json: "" |
11 |
# status: 1 |
12 |
|
13 |
### errexit for nonexistent command |
14 |
set -o errexit |
15 |
nonexistent__ZZ |
16 |
echo done |
17 |
# stdout-json: "" |
18 |
# status: 127 |
19 |
|
20 |
### errexit aborts early on pipeline |
21 |
set -o errexit |
22 |
echo hi | grep nonexistent |
23 |
echo two |
24 |
# stdout-json: "" |
25 |
# status: 1 |
26 |
|
27 |
### errexit with { } |
28 |
# This aborts because it's not part of an if statement. |
29 |
set -o errexit |
30 |
{ echo one; false; echo two; } |
31 |
# stdout: one |
32 |
# status: 1 |
33 |
|
34 |
### errexit with if and { } |
35 |
set -o errexit |
36 |
if { echo one; false; echo two; }; then |
37 |
echo three |
38 |
fi |
39 |
echo four |
40 |
## status: 0 |
41 |
## STDOUT: |
42 |
one |
43 |
two |
44 |
three |
45 |
four |
46 |
## END |
47 |
|
48 |
### errexit with || |
49 |
set -o errexit |
50 |
echo hi | grep nonexistent || echo ok |
51 |
# stdout: ok |
52 |
# status: 0 |
53 |
|
54 |
### errexit with && |
55 |
set -o errexit |
56 |
echo ok && echo hi | grep nonexistent |
57 |
# stdout: ok |
58 |
# status: 1 |
59 |
|
60 |
### errexit test && -- from gen-module-init |
61 |
set -o errexit |
62 |
test "$mod" = readline && echo "#endif" |
63 |
echo status=$? |
64 |
# stdout: status=1 |
65 |
|
66 |
### errexit test && and fail |
67 |
set -o errexit |
68 |
test -n X && false |
69 |
echo status=$? |
70 |
# stdout-json: "" |
71 |
# status: 1 |
72 |
|
73 |
### errexit and loop |
74 |
set -o errexit |
75 |
for x in 1 2 3; do |
76 |
test $x = 2 && echo "hi $x" |
77 |
done |
78 |
# stdout: hi 2 |
79 |
# status: 1 |
80 |
|
81 |
### errexit and brace group { } |
82 |
set -o errexit |
83 |
{ test no = yes && echo hi; } |
84 |
echo status=$? |
85 |
# stdout: status=1 |
86 |
|
87 |
### errexit and time { } |
88 |
set -o errexit |
89 |
time false |
90 |
echo status=$? |
91 |
# status: 1 |
92 |
|
93 |
### errexit with ! |
94 |
set -o errexit |
95 |
echo one |
96 |
! true |
97 |
echo two |
98 |
! false |
99 |
echo three |
100 |
## STDOUT: |
101 |
one |
102 |
two |
103 |
three |
104 |
## END |
105 |
|
106 |
### errexit with ! and ; |
107 |
# AST has extra Sentence nodes; there was a REGRESSION here. |
108 |
set -o errexit; echo one; ! true; echo two; ! false; echo three |
109 |
## STDOUT: |
110 |
one |
111 |
two |
112 |
three |
113 |
## END |
114 |
|
115 |
### errexit with while/until |
116 |
set -o errexit |
117 |
while false; do |
118 |
echo ok |
119 |
done |
120 |
until false; do |
121 |
echo ok # do this once then exit loop |
122 |
break |
123 |
done |
124 |
# stdout: ok |
125 |
# status: 0 |
126 |
|
127 |
### errexit with (( )) |
128 |
# from http://mywiki.wooledge.org/BashFAQ/105, this changed between verisons. |
129 |
# ash says that 'i++' is not found, but it doesn't exit. I guess this is the |
130 |
# subshell problem? |
131 |
set -o errexit |
132 |
i=0 |
133 |
(( i++ )) |
134 |
echo done |
135 |
# stdout-json: "" |
136 |
# status: 1 |
137 |
# N-I dash status: 127 |
138 |
# N-I dash stdout-json: "" |
139 |
# BUG ash status: 0 |
140 |
# BUG ash stdout: done |
141 |
|
142 |
### errexit with subshell |
143 |
set -o errexit |
144 |
( echo one; false; echo two; ) |
145 |
echo three |
146 |
## status: 1 |
147 |
## STDOUT: |
148 |
one |
149 |
## BUG ash status: 0 |
150 |
## BUG ash STDOUT: |
151 |
one |
152 |
three |
153 |
## END |
154 |
|
155 |
### setting errexit while it's being ignored |
156 |
# ignored and then set again |
157 |
set -o errexit |
158 |
# osh aborts early here |
159 |
if { echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4; }; then |
160 |
echo 5; |
161 |
fi |
162 |
echo 6 |
163 |
false # this is the one that makes other shells fail |
164 |
echo 7 |
165 |
## status: 1 |
166 |
## STDOUT: |
167 |
1 |
168 |
2 |
169 |
## END |
170 |
## OK dash/bash/mksh/ash STDOUT: |
171 |
1 |
172 |
2 |
173 |
3 |
174 |
4 |
175 |
5 |
176 |
6 |
177 |
## END |
178 |
|
179 |
### setting errexit in a subshell works but doesn't affect parent shell |
180 |
( echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4; ) |
181 |
echo 5 |
182 |
false |
183 |
echo 6 |
184 |
## STDOUT: |
185 |
1 |
186 |
2 |
187 |
3 |
188 |
5 |
189 |
6 |
190 |
## END |
191 |
|
192 |
### setting errexit while it's being ignored in a subshell |
193 |
set -o errexit |
194 |
if ( echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4 ); then |
195 |
echo 5; |
196 |
fi |
197 |
echo 6 # This is executed because the subshell just returns false |
198 |
false |
199 |
echo 7 |
200 |
## status: 1 |
201 |
## STDOUT: |
202 |
1 |
203 |
2 |
204 |
6 |
205 |
## OK dash/bash/mksh/ash STDOUT: |
206 |
1 |
207 |
2 |
208 |
3 |
209 |
4 |
210 |
5 |
211 |
6 |
212 |
## END |
213 |
|
214 |
### errexit double guard |
215 |
# OSH bug fix. ErrExit needs a counter, not a boolean. |
216 |
set -o errexit |
217 |
if { ! false; false; true; } then |
218 |
echo true |
219 |
fi |
220 |
false |
221 |
echo done |
222 |
## status: 1 |
223 |
## STDOUT: |
224 |
true |
225 |
## END |
226 |
|
227 |
### background processes respect errexit |
228 |
set -o errexit |
229 |
{ echo one; false; echo two; exit 42; } & |
230 |
wait $! |
231 |
## status: 1 |
232 |
## STDOUT: |
233 |
one |
234 |
## END |
235 |
|
236 |
### pipeline process respects errexit |
237 |
set -o errexit |
238 |
# It is respected here. |
239 |
{ echo one; false; echo two; } | cat |
240 |
|
241 |
# Also respected here. |
242 |
{ echo three; echo four; } | while read line; do |
243 |
echo "[$line]" |
244 |
false |
245 |
done |
246 |
echo four |
247 |
# status: 1 |
248 |
## STDOUT: |
249 |
one |
250 |
[three] |
251 |
## END |