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

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