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

287 lines, 141 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
78trap 'echo err' ERR
79#trap 'echo line=$LINENO' ERR
80
81# it's run for the last 'false'
82false | false | false
83
84# it's never run here
85! true
86! false
87
88## STDOUT:
89err
90## END
91
92#### trap ERR not active in shell functions in (bash behavior)
93
94trap 'echo line=$LINENO' ERR
95
96f() {
97 false
98 true
99}
100
101f
102
103## STDOUT:
104## END
105
106## N-I mksh STDOUT:
107line=4
108## END
109
110#### trap ERR shell function - with errtrace
111
112trap 'echo line=$LINENO' ERR
113
114passing() {
115 false # line 4
116 true
117}
118
119failing() {
120 true
121 false
122}
123
124passing
125failing
126
127set -o errtrace
128
129echo 'now with errtrace'
130passing
131failing
132
133echo ok
134
135## STDOUT:
136line=14
137now with errtrace
138line=4
139line=10
140line=20
141ok
142## END
143
144## BUG mksh status: 1
145## BUG mksh STDOUT:
146line=4
147line=10
148## END
149
150
151#### trap ERR with YSH proc
152
153case $SH in bash|mksh|ash) exit ;; esac
154
155# seems the same
156
157shopt -s ysh:upgrade
158
159proc abc { echo abc }
160if test -f /nope { echo file exists }
161trap abc ERR
162if test -f /nope { echo file exists }
163
164## STDOUT:
165abc
166## END
167
168## N-I bash/mksh/ash STDOUT:
169## END
170
171#### trap ERR
172err() {
173 echo "err [$@] $?"
174}
175trap 'err x y' ERR
176
177echo A
178
179false
180echo B
181
182( exit 42 )
183echo C
184
185trap - ERR # disable trap
186
187false
188echo D
189
190trap 'echo after errexit $?' ERR
191
192set -o errexit
193
194( exit 99 )
195echo E
196
197## status: 99
198## STDOUT:
199A
200err [x y] 1
201B
202err [x y] 42
203C
204D
205after errexit 99
206## END
207## N-I dash STDOUT:
208A
209B
210C
211D
212## END
213
214#### trap ERR and pipelines (lastpipe and PIPESTATUS difference)
215case $SH in ash) exit ;; esac
216
217err() {
218 echo "err [$@] status=$? [${PIPESTATUS[@]}]"
219}
220trap 'err' ERR
221
222echo A
223
224false
225
226# succeeds
227echo B | grep B
228
229# fails
230echo C | grep zzz
231
232echo D | grep zzz | cat
233
234set -o pipefail
235echo E | grep zzz | cat
236
237trap - ERR # disable trap
238
239echo F | grep zz
240echo ok
241
242## STDOUT:
243A
244err [] status=1 [1]
245B
246err [] status=1 [0 1]
247err [] status=1 [0 1 0]
248ok
249## END
250
251# lastpipe semantics mean we get another call!
252# also we don't set PIPESTATUS unless we get a pipeline
253
254## OK osh STDOUT:
255A
256err [] status=1 []
257B
258err [] status=1 [0 0]
259err [] status=1 [0 1]
260err [] status=1 [0 1 0]
261ok
262## END
263
264## N-I ash STDOUT:
265## END
266
267#### error in trap ERR (recursive)
268case $SH in dash) exit ;; esac
269
270err() {
271 echo err status $?
272 ( exit 2 )
273}
274trap 'err' ERR
275
276echo A
277false
278echo B
279
280## STDOUT:
281A
282err status 1
283B
284## END
285## N-I dash STDOUT:
286## END
287