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