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