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 sets PIPESTATUS
57 { echo hi; exit 55; } | { exit 99; } &
58 echo "pipestatus=${PIPESTATUS[@]}"
59 wait $!
60 echo status=$?
61 echo "pipestatus=${PIPESTATUS[@]}"
62 ## stdout-json: "pipestatus=\nstatus=99\npipestatus=55 99\n"
63 ## BUG bash stdout-json: "pipestatus=\nstatus=99\npipestatus=0\n"
64 ## N-I mksh stdout-json: "pipestatus=0\nstatus=99\npipestatus=0\n"
65 ## N-I dash stdout-json: ""
66 ## N-I dash status: 2
67
68 #### Brace group in background, wait all
69 { sleep 0.09; exit 9; } &
70 { sleep 0.07; exit 7; } &
71 wait # wait for all gives 0
72 echo "status=$?"
73 ## stdout: status=0
74
75 #### Wait on background process PID
76 { sleep 0.09; exit 9; } &
77 pid1=$!
78 { sleep 0.07; exit 7; } &
79 pid2=$!
80 wait $pid1
81 echo "status=$?"
82 wait $pid2
83 echo "status=$?"
84 ## stdout-json: "status=9\nstatus=7\n"
85
86 #### Wait on multiple specific IDs returns last status
87 { sleep 0.08; exit 8; } &
88 jid1=$!
89 { sleep 0.09; exit 9; } &
90 jid2=$!
91 { sleep 0.07; exit 7; } &
92 jid3=$!
93 wait $jid1 $jid2 $jid3 # NOTE: not using %1 %2 %3 syntax on purpose
94 echo "status=$?" # third job I think
95 ## stdout: status=7
96
97 #### wait -n
98 { sleep 0.09; exit 9; } &
99 { sleep 0.03; exit 3; } &
100 wait -n
101 echo "status=$?"
102 wait -n
103 echo "status=$?"
104 ## stdout-json: "status=3\nstatus=9\n"
105 ## N-I dash stdout-json: "status=2\nstatus=2\n"
106 ## N-I mksh stdout-json: "status=1\nstatus=1\n"
107
108 #### Async for loop
109 for i in 1 2 3; do
110 echo $i
111 sleep 0.0$i
112 done &
113 wait
114 ## stdout-json: "1\n2\n3\n"
115 ## status: 0
116
117 #### Background process doesn't affect parent
118 echo ${foo=1}
119 echo $foo
120 echo ${bar=2} &
121 wait
122 echo $bar # bar is NOT SET in the parent process
123 ## stdout-json: "1\n1\n2\n\n"