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