1 |
#!/usr/bin/env bash |
2 |
# |
3 |
# Job control constructs: |
4 |
# & terminator (instead of ;) |
5 |
# $! -- last PID |
6 |
# wait builtin (wait -n waits for next) |
7 |
# |
8 |
# Only interactive: |
9 |
# fg |
10 |
# bg |
11 |
# %1 -- current job |
12 |
|
13 |
#### wait with nothing to wait for |
14 |
wait |
15 |
## status: 0 |
16 |
|
17 |
#### wait -n with nothing to wait for |
18 |
# The 127 is STILL overloaded. Copying bash for now. |
19 |
wait -n |
20 |
## status: 127 |
21 |
## OK dash status: 2 |
22 |
## OK mksh status: 1 |
23 |
|
24 |
#### wait with jobspec syntax %nonexistent |
25 |
wait %nonexistent |
26 |
## status: 127 |
27 |
## OK dash status: 2 |
28 |
|
29 |
#### wait with invalid PID |
30 |
wait 12345678 |
31 |
## status: 127 |
32 |
|
33 |
#### wait with invalid arg |
34 |
wait zzz |
35 |
## status: 2 |
36 |
## OK bash status: 1 |
37 |
# mksh confuses a syntax error with 'command not found'! |
38 |
## BUG mksh status: 127 |
39 |
|
40 |
#### Builtin in background |
41 |
echo async & |
42 |
wait |
43 |
## stdout: async |
44 |
|
45 |
#### External command in background |
46 |
sleep 0.01 & |
47 |
wait |
48 |
## stdout-json: "" |
49 |
|
50 |
#### Pipeline in Background |
51 |
echo hi | { exit 99; } & |
52 |
wait $! |
53 |
echo status=$? |
54 |
## stdout: status=99 |
55 |
|
56 |
#### Wait for job doesn't support PIPESTATUS |
57 |
|
58 |
# foreground works |
59 |
{ echo hi; exit 55; } | { exit 99; } |
60 |
echo pipestatus=${PIPESTATUS[@]} |
61 |
|
62 |
# background doesn't work |
63 |
{ echo hi; exit 55; } | { exit 99; } & |
64 |
wait %+ |
65 |
echo pipestatus=${PIPESTATUS[@]} |
66 |
## STDOUT: |
67 |
pipestatus=55 99 |
68 |
pipestatus=99 |
69 |
## |
70 |
## N-I dash status: 2 |
71 |
## N-I dash stdout-json: "" |
72 |
|
73 |
#### Brace group in background, wait all |
74 |
{ sleep 0.09; exit 9; } & |
75 |
{ sleep 0.07; exit 7; } & |
76 |
wait # wait for all gives 0 |
77 |
echo "status=$?" |
78 |
## stdout: status=0 |
79 |
|
80 |
#### Wait on background process PID |
81 |
{ sleep 0.09; exit 9; } & |
82 |
pid1=$! |
83 |
{ sleep 0.07; exit 7; } & |
84 |
pid2=$! |
85 |
wait $pid1 |
86 |
echo "status=$?" |
87 |
wait $pid2 |
88 |
echo "status=$?" |
89 |
## stdout-json: "status=9\nstatus=7\n" |
90 |
|
91 |
#### Wait on multiple specific IDs returns last status |
92 |
{ sleep 0.08; exit 8; } & |
93 |
jid1=$! |
94 |
{ sleep 0.09; exit 9; } & |
95 |
jid2=$! |
96 |
{ sleep 0.07; exit 7; } & |
97 |
jid3=$! |
98 |
wait $jid1 $jid2 $jid3 # NOTE: not using %1 %2 %3 syntax on purpose |
99 |
echo "status=$?" # third job I think |
100 |
## stdout: status=7 |
101 |
|
102 |
#### wait -n |
103 |
{ sleep 0.09; exit 9; } & |
104 |
{ sleep 0.03; exit 3; } & |
105 |
wait -n |
106 |
echo "status=$?" |
107 |
wait -n |
108 |
echo "status=$?" |
109 |
## stdout-json: "status=3\nstatus=9\n" |
110 |
## N-I dash stdout-json: "status=2\nstatus=2\n" |
111 |
## N-I mksh stdout-json: "status=1\nstatus=1\n" |
112 |
|
113 |
#### Async for loop |
114 |
for i in 1 2 3; do |
115 |
echo $i |
116 |
sleep 0.0$i |
117 |
done & |
118 |
wait |
119 |
## stdout-json: "1\n2\n3\n" |
120 |
## status: 0 |
121 |
|
122 |
#### Background process doesn't affect parent |
123 |
echo ${foo=1} |
124 |
echo $foo |
125 |
echo ${bar=2} & |
126 |
wait |
127 |
echo $bar # bar is NOT SET in the parent process |
128 |
## stdout-json: "1\n1\n2\n\n" |
129 |
|
130 |
#### Background process and then a singleton pipeline |
131 |
|
132 |
# This was inspired by #416, although that symptom there was timing, so it's |
133 |
# technically not a regression test. It's hard to test timing. |
134 |
|
135 |
{ sleep 0.1; exit 42; } & |
136 |
echo begin |
137 |
! true |
138 |
echo end |
139 |
wait $! |
140 |
echo status=$? |
141 |
## STDOUT: |
142 |
begin |
143 |
end |
144 |
status=42 |
145 |
## END |