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

337 lines, 169 significant
1# builtin-trap.test.sh
2
3#### trap accepts/ignores --
4trap -- 'echo hi' EXIT
5echo done
6## STDOUT:
7done
8hi
9## END
10
11#### trap 'echo hi' KILL (regression test, caught by smoosh suite)
12trap 'echo hi' 9
13echo status=$?
14trap 'echo hi' KILL
15echo status=$?
16trap 'echo hi' STOP
17echo status=$?
18trap 'echo hi' TERM
19echo status=$?
20## STDOUT:
21status=0
22status=0
23status=0
24status=0
25## END
26## OK osh STDOUT:
27status=1
28status=1
29status=1
30status=0
31## END
32
33#### Register invalid trap
34trap 'foo' SIGINVALID
35## status: 1
36
37#### Remove invalid trap
38trap - SIGINVALID
39## status: 1
40
41#### SIGINT and INT are aliases
42trap - SIGINT
43echo $?
44trap - INT
45echo $?
46## STDOUT:
470
480
49## END
50## N-I dash STDOUT:
511
520
53## END
54
55#### Invalid trap invocation
56trap 'foo'
57echo status=$?
58## stdout: status=2
59## OK dash stdout: status=1
60## BUG mksh stdout: status=0
61
62#### exit 1 when trap code string is invalid
63# All shells spew warnings to stderr, but don't actually exit! Bad!
64trap 'echo <' EXIT
65echo status=$?
66## stdout: status=1
67## BUG mksh status: 1
68## BUG mksh stdout: status=0
69## BUG dash/bash status: 0
70## BUG dash/bash stdout: status=0
71
72#### trap EXIT calling exit
73cleanup() {
74 echo "cleanup [$@]"
75 exit 42
76}
77trap 'cleanup x y z' EXIT
78## stdout: cleanup [x y z]
79## status: 42
80
81#### trap EXIT return status ignored
82cleanup() {
83 echo "cleanup [$@]"
84 return 42
85}
86trap 'cleanup x y z' EXIT
87## stdout: cleanup [x y z]
88## status: 0
89
90#### trap EXIT with PARSE error
91trap 'echo FAILED' EXIT
92for
93## stdout: FAILED
94## status: 2
95## OK mksh status: 1
96
97#### trap EXIT with PARSE error and explicit exit
98trap 'echo FAILED; exit 0' EXIT
99for
100## stdout: FAILED
101## status: 0
102
103#### trap EXIT with explicit exit
104trap 'echo IN TRAP; echo $stdout' EXIT
105stdout=FOO
106exit 42
107
108## status: 42
109## STDOUT:
110IN TRAP
111FOO
112## END
113
114#### trap EXIT with command sub / subshell / pipeline
115trap 'echo EXIT TRAP' EXIT
116
117echo $(echo command sub)
118
119( echo subshell )
120
121echo pipeline | cat
122
123## STDOUT:
124command sub
125subshell
126pipeline
127EXIT TRAP
128## END
129
130#### trap ERR
131err() {
132 echo "err [$@] $?"
133}
134trap 'err x y' ERR
135
136echo A
137
138false
139echo B
140
141( exit 42 )
142echo C
143
144trap - ERR # disable trap
145
146false
147echo D
148
149trap 'echo after errexit $?' ERR
150
151set -o errexit
152
153( exit 99 )
154echo E
155
156## status: 99
157## STDOUT:
158A
159err [x y] 1
160B
161err [x y] 42
162C
163D
164after errexit 99
165## END
166## N-I dash STDOUT:
167A
168B
169C
170D
171## END
172
173#### trap ERR and pipelines (lastpipe and PIPESTATUS difference)
174case $SH in dash) exit ;; esac
175
176err() {
177 echo "err [$@] status=$? [${PIPESTATUS[@]}]"
178}
179trap 'err' ERR
180
181echo A
182
183false
184
185# succeeds
186echo B | grep B
187
188# fails
189echo C | grep zzz
190
191echo D | grep zzz | cat
192
193set -o pipefail
194echo E | grep zzz | cat
195
196trap - ERR # disable trap
197
198echo F | grep zz
199echo ok
200
201## STDOUT:
202A
203err [] status=1 [1]
204B
205err [] status=1 [0 1]
206err [] status=1 [0 1 0]
207ok
208## END
209
210# lastpipe semantics mean we get another call!
211# also we don't set PIPESTATUS unless we get a pipeline
212
213## OK osh STDOUT:
214A
215err [] status=1 []
216B
217err [] status=1 [0 0]
218err [] status=1 [0 1]
219err [] status=1 [0 1 0]
220ok
221## END
222
223## N-I dash STDOUT:
224## END
225
226#### error in trap ERR (recursive)
227case $SH in dash) exit ;; esac
228
229err() {
230 echo err status $?
231 ( exit 2 )
232}
233trap 'err' ERR
234
235echo A
236false
237echo B
238
239## STDOUT:
240A
241err status 1
242B
243## END
244## N-I dash STDOUT:
245## END
246
247#### trap 0 is equivalent to EXIT
248# not sure why this is, but POSIX wants it.
249trap 'echo EXIT' 0
250echo status=$?
251trap - EXIT
252echo status=$?
253## status: 0
254## STDOUT:
255status=0
256status=0
257## END
258
259#### trap 1 is equivalent to SIGHUP; HUP is equivalent to SIGHUP
260trap 'echo HUP' SIGHUP
261echo status=$?
262trap 'echo HUP' HUP
263echo status=$?
264trap 'echo HUP' 1
265echo status=$?
266trap - HUP
267echo status=$?
268## status: 0
269## STDOUT:
270status=0
271status=0
272status=0
273status=0
274## END
275## N-I dash STDOUT:
276status=1
277status=0
278status=0
279status=0
280## END
281
282#### eval in the exit trap (regression for issue #293)
283trap 'eval "echo hi"' 0
284## STDOUT:
285hi
286## END
287
288
289#### exit codes for traps are isolated
290
291trap 'echo USR1 trap status=$?; ( exit 42 )' USR1
292
293echo before=$?
294
295# Equivalent to 'kill -USR1 $$' except OSH doesn't have "kill" yet.
296# /bin/kill doesn't exist on Debian unless 'procps' is installed.
297sh -c "kill -USR1 $$"
298echo after=$?
299
300## STDOUT:
301before=0
302USR1 trap status=0
303after=0
304## END
305
306#### traps are cleared in subshell (started with &)
307
308# Test with SIGURG because the default handler is SIG_IGN
309#
310# If we use SIGUSR1, I think the shell reverts to killing the process
311
312# https://man7.org/linux/man-pages/man7/signal.7.html
313
314trap 'echo SIGURG' URG
315
316kill -URG $$
317
318# Hm trap doesn't happen here
319{ echo begin child; sleep 0.1; echo end child; } &
320kill -URG $!
321wait
322echo "wait status $?"
323
324# In the CI, mksh sometimes gives:
325#
326# USR1
327# begin child
328# done
329#
330# leaving off 'end child'. This seems like a BUG to me?
331
332## STDOUT:
333SIGURG
334begin child
335end child
336wait status 0
337## END