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 invalid job ID
25 wait %nonexistent
26 ## status: 127
27 ## OK dash status: 2
28
29 #### wait with invalid PID
30 wait %nonexistent
31 ## status: 127
32 ## OK dash status: 2
33
34 #### Builtin in background
35 echo async &
36 wait
37 ## stdout: async
38
39 #### External command in background
40 sleep 0.01 &
41 wait
42 ## stdout-json: ""
43
44 #### Pipeline in Background
45 echo hi | { exit 99; } &
46 wait $!
47 echo status=$?
48 ## stdout: status=99
49
50 #### Wait sets PIPESTATUS
51 { echo hi; exit 55; } | { exit 99; } &
52 echo "pipestatus=${PIPESTATUS[@]}"
53 wait $!
54 echo status=$?
55 echo "pipestatus=${PIPESTATUS[@]}"
56 ## stdout-json: "pipestatus=\nstatus=99\npipestatus=55 99\n"
57 ## BUG bash stdout-json: "pipestatus=\nstatus=99\npipestatus=0\n"
58 ## N-I mksh stdout-json: "pipestatus=0\nstatus=99\npipestatus=0\n"
59 ## N-I dash stdout-json: ""
60 ## N-I dash status: 2
61
62 #### Brace group in background, wait all
63 { sleep 0.09; exit 9; } &
64 { sleep 0.07; exit 7; } &
65 wait # wait for all gives 0
66 echo "status=$?"
67 ## stdout: status=0
68
69 #### Wait on background process PID
70 { sleep 0.09; exit 9; } &
71 pid1=$!
72 { sleep 0.07; exit 7; } &
73 pid2=$!
74 wait $pid1
75 echo "status=$?"
76 wait $pid2
77 echo "status=$?"
78 ## stdout-json: "status=9\nstatus=7\n"
79
80 #### Wait on multiple specific IDs returns last status
81 { sleep 0.08; exit 8; } &
82 jid1=$!
83 { sleep 0.09; exit 9; } &
84 jid2=$!
85 { sleep 0.07; exit 7; } &
86 jid3=$!
87 wait $jid1 $jid2 $jid3 # NOTE: not using %1 %2 %3 syntax on purpose
88 echo "status=$?" # third job I think
89 ## stdout: status=7
90
91 #### wait -n
92 { sleep 0.09; exit 9; } &
93 { sleep 0.03; exit 3; } &
94 wait -n
95 echo "status=$?"
96 wait -n
97 echo "status=$?"
98 ## stdout-json: "status=3\nstatus=9\n"
99 ## N-I dash stdout-json: "status=2\nstatus=2\n"
100 ## N-I mksh stdout-json: "status=1\nstatus=1\n"
101
102 #### Async for loop
103 for i in 1 2 3; do
104 echo $i
105 sleep 0.0$i
106 done &
107 wait
108 ## stdout-json: "1\n2\n3\n"
109 ## status: 0
110
111 #### Background process doesn't affect parent
112 echo ${foo=1}
113 echo $foo
114 echo ${bar=2} &
115 wait
116 echo $bar # bar is NOT SET in the parent process
117 ## stdout-json: "1\n1\n2\n\n"