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

398 lines, 197 significant
1## oils_failures_allowed: 3
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## OK 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
166#### Wait for job and PIPESTATUS
167
168# foreground
169{ echo hi; exit 55; } | false
170echo fore status=$? pipestatus=${PIPESTATUS[@]}
171
172# background
173{ echo hi; exit 44; } | false &
174echo back status=$? pipestatus=${PIPESTATUS[@]}
175
176# wait for pipeline
177wait %+
178#wait %1
179#wait $!
180echo wait status=$? pipestatus=${PIPESTATUS[@]}
181
182## STDOUT:
183fore status=1 pipestatus=55 1
184back status=0 pipestatus=0
185wait status=1 pipestatus=1
186## END
187## N-I dash status: 2
188## N-I dash STDOUT:
189## END
190
191#### Wait for job and PIPESTATUS - cat
192
193# foreground
194exit 55 | ( cat; exit 99 )
195echo fore status=$? pipestatus=${PIPESTATUS[@]}
196
197# background
198exit 44 | ( cat; exit 88 ) &
199echo back status=$? pipestatus=${PIPESTATUS[@]}
200
201# wait for pipeline
202wait %+
203#wait %1
204#wait $!
205echo wait status=$? pipestatus=${PIPESTATUS[@]}
206echo
207
208# wait for non-pipeline
209( exit 77 ) &
210wait %+
211echo wait status=$? pipestatus=${PIPESTATUS[@]}
212
213## STDOUT:
214fore status=99 pipestatus=55 99
215back status=0 pipestatus=0
216wait status=88 pipestatus=88
217
218wait status=77 pipestatus=77
219## END
220## N-I dash status: 2
221## N-I dash STDOUT:
222## END
223
224#### Brace group in background, wait all
225{ sleep 0.09; exit 9; } &
226{ sleep 0.07; exit 7; } &
227wait # wait for all gives 0
228echo "status=$?"
229## stdout: status=0
230
231#### Wait on background process PID
232{ sleep 0.09; exit 9; } &
233pid1=$!
234{ sleep 0.07; exit 7; } &
235pid2=$!
236wait $pid2
237echo "status=$?"
238wait $pid1
239echo "status=$?"
240## STDOUT:
241status=7
242status=9
243## END
244
245#### Wait on multiple specific IDs returns last status
246{ sleep 0.08; exit 8; } &
247jid1=$!
248{ sleep 0.09; exit 9; } &
249jid2=$!
250{ sleep 0.07; exit 7; } &
251jid3=$!
252wait $jid1 $jid2 $jid3 # NOTE: not using %1 %2 %3 syntax on purpose
253echo "status=$?" # third job I think
254## stdout: status=7
255
256#### wait -n
257case $SH in (dash|mksh) return ;; esac
258
259{ sleep 0.09; exit 9; } &
260{ sleep 0.03; exit 3; } &
261wait -n
262echo "status=$?"
263wait -n
264echo "status=$?"
265## STDOUT:
266status=3
267status=9
268## END
269## N-I dash/mksh stdout-json: ""
270
271#### Async for loop
272for i in 1 2 3; do
273 echo $i
274 sleep 0.0$i
275done &
276wait
277## STDOUT:
2781
2792
2803
281## END
282## status: 0
283
284#### Background process doesn't affect parent
285echo ${foo=1}
286echo $foo
287echo ${bar=2} &
288wait
289echo $bar # bar is NOT SET in the parent process
290## STDOUT:
2911
2921
2932
294
295## END
296
297#### Background process and then a singleton pipeline
298
299# This was inspired by #416, although that symptom there was timing, so it's
300# technically not a regression test. It's hard to test timing.
301
302{ sleep 0.1; exit 42; } &
303echo begin
304! true
305echo end
306wait $!
307echo status=$?
308## STDOUT:
309begin
310end
311status=42
312## END
313
314#### jobs prints one line per job
315sleep 0.1 &
316sleep 0.1 | cat &
317
318# dash doesn't print if it's not a terminal?
319jobs | wc -l
320
321## STDOUT:
3222
323## END
324## BUG dash STDOUT:
3250
326## END
327
328#### jobs -p prints one line per job
329sleep 0.1 &
330sleep 0.1 | cat &
331
332jobs -p > tmp.txt
333
334cat tmp.txt | wc -l # 2 lines, one for each job
335cat tmp.txt | wc -w # each line is a single "word"
336
337## STDOUT:
3382
3392
340## END
341
342
343#### No stderr spew when shell is not interactive
344
345# in interactive shell, this prints 'Process' or 'Pipeline'
346sleep 0.01 &
347sleep 0.01 | cat &
348wait
349
350## STDOUT:
351## END
352## STDERR:
353## END
354
355
356#### YSH wait --all
357case $SH in dash|bash|mksh) exit ;; esac
358
359sleep 0.01 &
360(exit 55) &
361true &
362wait
363echo wait $?
364
365sleep 0.01 &
366(exit 44) &
367true &
368wait --all
369echo wait --all $?
370
371## STDOUT:
372wait 0
373wait --all 1
374## END
375
376## N-I dash/bash/mksh STDOUT:
377## END
378
379#### YSH wait --verbose
380case $SH in dash|bash|mksh) exit ;; esac
381
382sleep 0.01 &
383(exit 55) &
384wait --verbose
385echo wait $?
386
387(exit 44) &
388sleep 0.01 &
389wait --all --verbose
390echo wait --all $?
391
392## STDOUT:
393wait 0
394wait --all 1
395## END
396
397## N-I dash/bash/mksh STDOUT:
398## END