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

306 lines, 153 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 nothing to wait for
19# The 127 is STILL overloaded. Copying bash for now.
20wait -n
21## status: 127
22## N-I dash status: 2
23## N-I mksh status: 1
24
25#### wait with jobspec syntax %nonexistent
26wait %nonexistent
27## status: 127
28## OK dash status: 2
29
30#### wait with invalid PID
31wait 12345678
32## status: 127
33
34#### wait with invalid arg
35wait zzz
36## status: 2
37## OK bash status: 1
38# mksh confuses a syntax error with 'command not found'!
39## BUG mksh status: 127
40
41#### wait for N parallel jobs
42
43for i in 3 2 1; do
44 { sleep 0.0$i; exit $i; } &
45done
46wait
47
48# status is lost
49echo status=$?
50
51## STDOUT:
52status=0
53## END
54
55#### wait for N parallel jobs and check failure
56
57set -o errexit
58
59pids=''
60for i in 3 2 1; do
61 { sleep 0.0$i; echo $i; exit $i; } &
62 pids="$pids $!"
63done
64
65for pid in $pids; do
66 set +o errexit
67 wait $pid
68 status=$?
69 set -o errexit
70
71 echo status=$status
72done
73
74## STDOUT:
751
762
773
78status=3
79status=2
80status=1
81## END
82
83#### Builtin in background
84echo async &
85wait
86## stdout: async
87
88#### External command in background
89sleep 0.01 &
90wait
91## stdout-json: ""
92
93#### Start background pipeline, wait $pid
94echo hi | { exit 99; } &
95echo status=$?
96wait $!
97echo status=$?
98echo --
99
100pids=''
101for i in 3 2 1; do
102 sleep 0.0$i | echo i=$i | ( exit $i ) &
103 pids="$pids $!"
104done
105#echo "PIDS $pids"
106
107for pid in $pids; do
108 wait $pid
109 echo status=$?
110done
111
112# Not cleaned up
113if false; then
114 echo 'DEBUG'
115 jobs --debug
116fi
117
118## STDOUT:
119status=0
120status=99
121--
122status=3
123status=2
124status=1
125## END
126
127#### Start background pipeline, wait %job_spec
128echo hi | { exit 99; } &
129echo status=$?
130wait %1
131echo status=$?
132## STDOUT:
133status=0
134status=99
135## END
136
137#### Wait for job and PIPESTATUS
138
139# foreground
140{ echo hi; exit 55; } | false
141echo status=$? pipestatus=${PIPESTATUS[@]}
142
143# background
144{ echo hi; exit 55; } | false &
145echo status=$? pipestatus=${PIPESTATUS[@]}
146
147# wait for pipeline
148wait %+
149#wait %1
150#wait $!
151echo status=$? pipestatus=${PIPESTATUS[@]}
152
153## STDOUT:
154status=1 pipestatus=55 1
155status=0 pipestatus=0
156status=1 pipestatus=1
157## END
158## N-I dash status: 2
159## N-I dash STDOUT:
160## END
161
162#### Wait for job and PIPESTATUS - cat
163
164# foreground
165{ echo hi; exit 55; } | ( cat; exit 99 )
166echo status=$? pipestatus=${PIPESTATUS[@]}
167
168# background
169{ echo hi; exit 55; } | ( cat; exit 99 ) &
170echo status=$? pipestatus=${PIPESTATUS[@]}
171
172# wait for pipeline
173wait %+
174#wait %1
175#wait $!
176echo status=$? pipestatus=${PIPESTATUS[@]}
177
178## STDOUT:
179hi
180status=99 pipestatus=55 99
181status=0 pipestatus=0
182hi
183status=99 pipestatus=99
184## END
185## N-I dash status: 2
186## N-I dash STDOUT:
187hi
188## END
189
190#### Brace group in background, wait all
191{ sleep 0.09; exit 9; } &
192{ sleep 0.07; exit 7; } &
193wait # wait for all gives 0
194echo "status=$?"
195## stdout: status=0
196
197#### Wait on background process PID
198{ sleep 0.09; exit 9; } &
199pid1=$!
200{ sleep 0.07; exit 7; } &
201pid2=$!
202wait $pid2
203echo "status=$?"
204wait $pid1
205echo "status=$?"
206## STDOUT:
207status=7
208status=9
209## END
210
211#### Wait on multiple specific IDs returns last status
212{ sleep 0.08; exit 8; } &
213jid1=$!
214{ sleep 0.09; exit 9; } &
215jid2=$!
216{ sleep 0.07; exit 7; } &
217jid3=$!
218wait $jid1 $jid2 $jid3 # NOTE: not using %1 %2 %3 syntax on purpose
219echo "status=$?" # third job I think
220## stdout: status=7
221
222#### wait -n
223case $SH in (dash|mksh) return ;; esac
224
225{ sleep 0.09; exit 9; } &
226{ sleep 0.03; exit 3; } &
227wait -n
228echo "status=$?"
229wait -n
230echo "status=$?"
231## STDOUT:
232status=3
233status=9
234## END
235## N-I dash/mksh stdout-json: ""
236
237#### Async for loop
238for i in 1 2 3; do
239 echo $i
240 sleep 0.0$i
241done &
242wait
243## STDOUT:
2441
2452
2463
247## END
248## status: 0
249
250#### Background process doesn't affect parent
251echo ${foo=1}
252echo $foo
253echo ${bar=2} &
254wait
255echo $bar # bar is NOT SET in the parent process
256## STDOUT:
2571
2581
2592
260
261## END
262
263#### Background process and then a singleton pipeline
264
265# This was inspired by #416, although that symptom there was timing, so it's
266# technically not a regression test. It's hard to test timing.
267
268{ sleep 0.1; exit 42; } &
269echo begin
270! true
271echo end
272wait $!
273echo status=$?
274## STDOUT:
275begin
276end
277status=42
278## END
279
280#### jobs prints one line per job
281sleep 0.1 &
282sleep 0.1 | cat &
283
284# dash doesn't print if it's not a terminal?
285jobs | wc -l
286
287## STDOUT:
2882
289## END
290## BUG dash STDOUT:
2910
292## END
293
294#### jobs -p prints one line per job
295sleep 0.1 &
296sleep 0.1 | cat &
297
298jobs -p > tmp.txt
299
300cat tmp.txt | wc -l # 2 lines, one for each job
301cat tmp.txt | wc -w # each line is a single "word"
302
303## STDOUT:
3042
3052
306## END