OILS / spec / background.test.sh View on Github | oils.pub

418 lines, 207 significant
1## oils_failures_allowed: 8
2## compare_shells: dash bash mksh
3
4# Job control constructs:
5# & terminator (instead of ;)
6# $! -- last PID
7# wait builtin (wait -n waits for next)
8#
9# Only interactive:
10# fg
11# bg
12# %1 -- current job
13
14#### wait with nothing to wait for
15wait
16## status: 0
17
18#### wait -n with arguments - arguments are respected
19case $SH in dash|mksh) exit ;; esac
20
21echo x &
22
23# here, you can't tell if it's -n or the other
24wait -n $!
25echo status=$?
26
27# by the bash error, you can tell which is preferred
28wait -n $! bad 2>err.txt
29echo status=$?
30echo
31
32n=$(wc -l < err.txt)
33if test "$n" -gt 0; then
34 echo 'got error lines'
35fi
36
37## STDOUT:
38x
39status=0
40status=127
41
42got error lines
43## END
44## N-I dash/mksh STDOUT:
45## END
46
47#### wait -n with nothing to wait for
48# The 127 is STILL overloaded. Copying bash for now.
49wait -n
50## status: 127
51## N-I dash status: 2
52## N-I mksh status: 1
53
54#### wait with jobspec syntax %nonexistent
55wait %nonexistent
56## status: 127
57## N-I dash status: 2
58
59#### wait with invalid PID
60wait 12345678
61## status: 127
62
63#### wait with invalid arg
64wait zzz
65## status: 2
66## OK bash status: 1
67# mksh confuses a syntax error with 'command not found'!
68## BUG mksh status: 127
69
70#### wait for N parallel jobs
71
72for i in 3 2 1; do
73 { sleep 0.0$i; exit $i; } &
74done
75wait
76
77# status is lost
78echo status=$?
79
80## STDOUT:
81status=0
82## END
83
84#### wait for N parallel jobs and check failure
85
86set -o errexit
87
88pids=''
89for i in 3 2 1; do
90 { sleep 0.0$i; echo $i; exit $i; } &
91 pids="$pids $!"
92done
93
94for pid in $pids; do
95 set +o errexit
96 wait $pid
97 status=$?
98 set -o errexit
99
100 echo status=$status
101done
102
103## STDOUT:
1041
1052
1063
107status=3
108status=2
109status=1
110## END
111
112#### Builtin in background
113echo async &
114wait
115## stdout: async
116
117#### External command in background
118sleep 0.01 &
119wait
120## stdout-json: ""
121
122#### Start background pipeline, wait $pid
123echo hi | { exit 99; } &
124echo status=$?
125wait $!
126echo status=$?
127echo --
128
129pids=''
130for i in 3 2 1; do
131 sleep 0.0$i | echo i=$i | ( exit $i ) &
132 pids="$pids $!"
133done
134#echo "PIDS $pids"
135
136for pid in $pids; do
137 wait $pid
138 echo status=$?
139done
140
141# Not cleaned up
142if false; then
143 echo 'DEBUG'
144 jobs --debug
145fi
146
147## STDOUT:
148status=0
149status=99
150--
151status=3
152status=2
153status=1
154## END
155
156#### Start background pipeline, wait %job_spec
157echo hi | { exit 99; } &
158echo status=$?
159wait %1
160echo status=$?
161## STDOUT:
162status=0
163status=99
164## END
165## N-I mksh STDOUT:
166status=0
167status=127
168## END
169
170#### Wait for job and PIPESTATUS
171
172# foreground
173{ echo hi; exit 55; } | false
174echo fore status=$? pipestatus=${PIPESTATUS[@]}
175
176# background
177{ echo hi; exit 44; } | false &
178echo back status=$? pipestatus=${PIPESTATUS[@]}
179
180# wait for pipeline
181wait %+
182#wait %1
183#wait $!
184echo wait status=$? pipestatus=${PIPESTATUS[@]}
185
186## STDOUT:
187fore status=1 pipestatus=55 1
188back status=0 pipestatus=0
189wait status=1 pipestatus=1
190## END
191## N-I dash status: 2
192## N-I dash STDOUT:
193## END
194
195#### Wait for job and PIPESTATUS - cat
196
197# foreground
198exit 55 | ( cat; exit 99 )
199echo fore status=$? pipestatus=${PIPESTATUS[@]}
200
201# background
202exit 44 | ( cat; exit 88 ) &
203echo back status=$? pipestatus=${PIPESTATUS[@]}
204
205# wait for pipeline
206wait %+
207#wait %1
208#wait $!
209echo wait status=$? pipestatus=${PIPESTATUS[@]}
210echo
211
212# wait for non-pipeline
213( exit 77 ) &
214wait %+
215echo wait status=$? pipestatus=${PIPESTATUS[@]}
216
217## STDOUT:
218fore status=99 pipestatus=55 99
219back status=0 pipestatus=0
220wait status=88 pipestatus=88
221
222wait status=77 pipestatus=77
223## END
224## N-I dash status: 2
225## N-I dash STDOUT:
226## END
227
228#### Brace group in background, wait all
229{ sleep 0.09; exit 9; } &
230{ sleep 0.07; exit 7; } &
231wait # wait for all gives 0
232echo "status=$?"
233## stdout: status=0
234
235#### Wait on background process PID
236{ sleep 0.09; exit 9; } &
237pid1=$!
238{ sleep 0.07; exit 7; } &
239pid2=$!
240wait $pid2
241echo "status=$?"
242wait $pid1
243echo "status=$?"
244## STDOUT:
245status=7
246status=9
247## END
248
249#### Wait on multiple specific IDs returns last status
250{ sleep 0.08; exit 8; } &
251jid1=$!
252{ sleep 0.09; exit 9; } &
253jid2=$!
254{ sleep 0.07; exit 7; } &
255jid3=$!
256wait $jid1 $jid2 $jid3 # NOTE: not using %1 %2 %3 syntax on purpose
257echo "status=$?" # third job I think
258## stdout: status=7
259
260#### wait -n
261case $SH in dash|mksh) return ;; esac
262
263{ sleep 0.09; exit 9; } &
264{ sleep 0.03; exit 3; } &
265wait -n
266echo "status=$?"
267wait -n
268echo "status=$?"
269## STDOUT:
270status=3
271status=9
272## END
273## N-I dash/mksh stdout-json: ""
274
275#### Async for loop
276for i in 1 2 3; do
277 echo $i
278 sleep 0.0$i
279done &
280wait
281## STDOUT:
2821
2832
2843
285## END
286## status: 0
287
288#### Background process doesn't affect parent
289echo ${foo=1}
290echo $foo
291echo ${bar=2} &
292wait
293echo $bar # bar is NOT SET in the parent process
294## STDOUT:
2951
2961
2972
298
299## END
300
301#### Background process and then a singleton pipeline
302
303# This was inspired by #416, although that symptom there was timing, so it's
304# technically not a regression test. It's hard to test timing.
305
306{ sleep 0.1; exit 42; } &
307echo begin
308! true
309echo end
310wait $!
311echo status=$?
312## STDOUT:
313begin
314end
315status=42
316## END
317
318#### jobs prints one line per job
319sleep 0.1 &
320sleep 0.1 | cat &
321
322# dash doesn't print if it's not a terminal?
323jobs | wc -l
324
325## STDOUT:
3262
327## END
328## BUG dash STDOUT:
3290
330## END
331
332#### jobs -p prints one line per job
333sleep 0.1 &
334sleep 0.1 | cat &
335
336jobs -p > tmp.txt
337
338cat tmp.txt | wc -l # 2 lines, one for each job
339cat tmp.txt | wc -w # each line is a single "word"
340
341## STDOUT:
3422
3432
344## END
345
346
347#### No stderr spew when shell is not interactive
348
349# in interactive shell, this prints 'Process' or 'Pipeline'
350sleep 0.01 &
351sleep 0.01 | cat &
352wait
353
354## STDOUT:
355## END
356## STDERR:
357## END
358
359
360#### YSH wait --all
361case $SH in dash|bash|mksh) exit ;; esac
362
363sleep 0.01 &
364(exit 55) &
365true &
366wait
367echo wait $?
368
369sleep 0.01 &
370(exit 44) &
371true &
372wait --all
373echo wait --all $?
374
375## STDOUT:
376wait 0
377wait --all 1
378## END
379
380## N-I dash/bash/mksh STDOUT:
381## END
382
383#### YSH wait --verbose
384case $SH in dash|bash|mksh) exit ;; esac
385
386sleep 0.01 &
387(exit 55) &
388wait --verbose
389echo wait $?
390
391(exit 44) &
392sleep 0.01 &
393wait --all --verbose
394echo wait --all $?
395
396## STDOUT:
397wait 0
398wait --all 1
399## END
400
401## N-I dash/bash/mksh STDOUT:
402## END
403
404#### Signal message for killed background job
405case $SH in dash|mksh) exit ;; esac
406
407sleep 1 &
408kill -HUP $!
409wait $! 2>err.txt
410echo status=$?
411grep -o "Hangup" err.txt
412## status: 0
413## STDOUT:
414status=129
415Hangup
416## END
417## STDERR:
418## END