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 #### Pipeline in Background
94 echo hi | { exit 99; } &
95 wait $!
96 echo status=$?
97 ## stdout: status=99
98
99 #### Wait for job and PIPESTATUS
100
101 # foreground
102 { echo hi; exit 55; } | false
103 echo status=$? pipestatus=${PIPESTATUS[@]}
104
105 # background
106 { echo hi; exit 55; } | false &
107 echo status=$? pipestatus=${PIPESTATUS[@]}
108
109 # wait for pipeline
110 wait %+
111 #wait %1
112 #wait $!
113 echo status=$? pipestatus=${PIPESTATUS[@]}
114
115 ## STDOUT:
116 status=1 pipestatus=55 1
117 status=0 pipestatus=0
118 status=1 pipestatus=1
119 ## END
120 ## N-I dash status: 2
121 ## N-I dash STDOUT:
122 ## END
123
124 #### Wait for job and PIPESTATUS - cat
125
126 # foreground
127 { echo hi; exit 55; } | ( cat; exit 99 )
128 echo status=$? pipestatus=${PIPESTATUS[@]}
129
130 # background
131 { echo hi; exit 55; } | ( cat; exit 99 ) &
132 echo status=$? pipestatus=${PIPESTATUS[@]}
133
134 # wait for pipeline
135 wait %+
136 #wait %1
137 #wait $!
138 echo status=$? pipestatus=${PIPESTATUS[@]}
139
140 ## STDOUT:
141 hi
142 status=99 pipestatus=55 99
143 status=0 pipestatus=0
144 hi
145 status=99 pipestatus=99
146 ## END
147 ## N-I dash status: 2
148 ## N-I dash STDOUT:
149 hi
150 ## END
151
152 #### Brace group in background, wait all
153 { sleep 0.09; exit 9; } &
154 { sleep 0.07; exit 7; } &
155 wait # wait for all gives 0
156 echo "status=$?"
157 ## stdout: status=0
158
159 #### Wait on background process PID
160 { sleep 0.09; exit 9; } &
161 pid1=$!
162 { sleep 0.07; exit 7; } &
163 pid2=$!
164 wait $pid2
165 echo "status=$?"
166 wait $pid1
167 echo "status=$?"
168 ## STDOUT:
169 status=7
170 status=9
171 ## END
172
173 #### Wait on multiple specific IDs returns last status
174 { sleep 0.08; exit 8; } &
175 jid1=$!
176 { sleep 0.09; exit 9; } &
177 jid2=$!
178 { sleep 0.07; exit 7; } &
179 jid3=$!
180 wait $jid1 $jid2 $jid3 # NOTE: not using %1 %2 %3 syntax on purpose
181 echo "status=$?" # third job I think
182 ## stdout: status=7
183
184 #### wait -n
185 case $SH in (dash|mksh) return ;; esac
186
187 { sleep 0.09; exit 9; } &
188 { sleep 0.03; exit 3; } &
189 wait -n
190 echo "status=$?"
191 wait -n
192 echo "status=$?"
193 ## STDOUT:
194 status=3
195 status=9
196 ## END
197 ## N-I dash/mksh stdout-json: ""
198
199 #### Async for loop
200 for i in 1 2 3; do
201 echo $i
202 sleep 0.0$i
203 done &
204 wait
205 ## STDOUT:
206 1
207 2
208 3
209 ## END
210 ## status: 0
211
212 #### Background process doesn't affect parent
213 echo ${foo=1}
214 echo $foo
215 echo ${bar=2} &
216 wait
217 echo $bar # bar is NOT SET in the parent process
218 ## STDOUT:
219 1
220 1
221 2
222
223 ## END
224
225 #### Background process and then a singleton pipeline
226
227 # This was inspired by #416, although that symptom there was timing, so it's
228 # technically not a regression test. It's hard to test timing.
229
230 { sleep 0.1; exit 42; } &
231 echo begin
232 ! true
233 echo end
234 wait $!
235 echo status=$?
236 ## STDOUT:
237 begin
238 end
239 status=42
240 ## END
241
242 #### jobs prints one line per job
243 sleep 0.1 &
244 sleep 0.1 | cat &
245
246 # dash doesn't print if it's not a terminal?
247 jobs | wc -l
248
249 ## STDOUT:
250 2
251 ## END
252 ## BUG dash STDOUT:
253 0
254 ## END
255
256 #### jobs -p prints one line per job
257 sleep 0.1 &
258 sleep 0.1 | cat &
259
260 jobs -p > tmp.txt
261
262 cat tmp.txt | wc -l # 2 lines, one for each job
263 cat tmp.txt | wc -w # each line is a single "word"
264
265 ## STDOUT:
266 2
267 2
268 ## END