OILS / spec / builtin-trap-err.test.sh View on Github | oilshell.org

317 lines, 156 significant
1## oils_failures_allowed: 5
2## compare_shells: bash mksh ash
3
4# Notes on bash semantics:
5#
6# https://www.gnu.org/software/bash/manual/bash.html
7#
8# The trap builtin (see Bourne Shell Builtins) allows an ERR pseudo-signal
9# specification, similar to EXIT and DEBUG. Commands specified with an ERR trap
10# are executed after a simple command fails, with a few exceptions. The ERR
11# trap is not inherited by shell functions unless the -o errtrace option to the
12# set builtin is enabled.
13
14
15#### trap can use original $LINENO
16
17trap 'echo line=$LINENO' ERR
18
19false
20false
21echo ok
22
23## STDOUT:
24line=3
25line=4
26ok
27## END
28
29#### trap ERR and if statement
30
31if test -f /nope; then echo file exists; fi
32
33trap 'echo err' ERR
34#trap 'echo line=$LINENO' ERR
35
36if test -f /nope; then echo file exists; fi
37
38## STDOUT:
39## END
40
41#### trap ERR does not run in errexit situations
42
43trap 'echo line=$LINENO' ERR
44
45if false; then
46 echo if
47fi
48
49while false; do
50 echo while
51done
52
53until false; do
54 echo until
55 break
56done
57
58false || false || false
59
60false && false && false
61
62false; false; false
63
64echo ok
65
66## STDOUT:
67until
68line=16
69line=20
70line=20
71line=20
72ok
73## END
74
75#### trap ERR pipeline (also errexit)
76
77# mksh and bash have different line numbers in this case
78#trap 'echo line=$LINENO' ERR
79trap 'echo line=$LINENO' ERR
80
81# it's run for the last 'false'
82false | false | false
83
84{ echo pipeline; false; } | false | false
85
86# it's never run here
87! true
88! false
89
90## STDOUT:
91line=3
92line=5
93## END
94
95## BUG mksh/ash STDOUT:
96line=1
97line=1
98## END
99
100#### trap ERR subprogram - subshell, command sub, async
101
102trap 'echo line=$LINENO' ERR
103
104( false; echo subshell )
105
106x=$( false; echo command sub )
107
108false & wait
109
110{ false; echo async; } & wait
111
112false
113echo ok
114
115## STDOUT:
116subshell
117async
118line=11
119ok
120## END
121
122#### trap ERR not active in shell functions in (bash behavior)
123
124trap 'echo line=$LINENO' ERR
125
126f() {
127 false
128 true
129}
130
131f
132
133## STDOUT:
134## END
135
136## N-I mksh STDOUT:
137line=4
138## END
139
140#### trap ERR shell function - with errtrace
141
142trap 'echo line=$LINENO' ERR
143
144passing() {
145 false # line 4
146 true
147}
148
149failing() {
150 true
151 false
152}
153
154passing
155failing
156
157set -o errtrace
158
159echo 'now with errtrace'
160passing
161failing
162
163echo ok
164
165## STDOUT:
166line=14
167now with errtrace
168line=4
169line=10
170line=20
171ok
172## END
173
174## BUG mksh status: 1
175## BUG mksh STDOUT:
176line=4
177line=10
178## END
179
180
181#### trap ERR with YSH proc
182
183case $SH in bash|mksh|ash) exit ;; esac
184
185# seems the same
186
187shopt -s ysh:upgrade
188
189proc abc { echo abc }
190if test -f /nope { echo file exists }
191trap abc ERR
192if test -f /nope { echo file exists }
193
194## STDOUT:
195abc
196## END
197
198## N-I bash/mksh/ash STDOUT:
199## END
200
201#### trap ERR
202err() {
203 echo "err [$@] $?"
204}
205trap 'err x y' ERR
206
207echo A
208
209false
210echo B
211
212( exit 42 )
213echo C
214
215trap - ERR # disable trap
216
217false
218echo D
219
220trap 'echo after errexit $?' ERR
221
222set -o errexit
223
224( exit 99 )
225echo E
226
227## status: 99
228## STDOUT:
229A
230err [x y] 1
231B
232err [x y] 42
233C
234D
235after errexit 99
236## END
237## N-I dash STDOUT:
238A
239B
240C
241D
242## END
243
244#### trap ERR and pipelines (lastpipe and PIPESTATUS difference)
245case $SH in ash) exit ;; esac
246
247err() {
248 echo "err [$@] status=$? [${PIPESTATUS[@]}]"
249}
250trap 'err' ERR
251
252echo A
253
254false
255
256# succeeds
257echo B | grep B
258
259# fails
260echo C | grep zzz
261
262echo D | grep zzz | cat
263
264set -o pipefail
265echo E | grep zzz | cat
266
267trap - ERR # disable trap
268
269echo F | grep zz
270echo ok
271
272## STDOUT:
273A
274err [] status=1 [1]
275B
276err [] status=1 [0 1]
277err [] status=1 [0 1 0]
278ok
279## END
280
281# lastpipe semantics mean we get another call!
282# also we don't set PIPESTATUS unless we get a pipeline
283
284## OK osh STDOUT:
285A
286err [] status=1 []
287B
288err [] status=1 [0 0]
289err [] status=1 [0 1]
290err [] status=1 [0 1 0]
291ok
292## END
293
294## N-I ash STDOUT:
295## END
296
297#### error in trap ERR (recursive)
298case $SH in dash) exit ;; esac
299
300err() {
301 echo err status $?
302 ( exit 2 )
303}
304trap 'err' ERR
305
306echo A
307false
308echo B
309
310## STDOUT:
311A
312err status 1
313B
314## END
315## N-I dash STDOUT:
316## END
317