In the following I create a background process and wait for it to complete.
$ bash -c "sleep 5 | false" & wait $!
[1] 46950
[1]+ Exit 1 bash -c "sleep 5 | false"
$ echo $?
1
This works and the prompt returns after 5 seconds.
However, wait
returns an error if I use one more pipe after it.
$ bash -c "sleep 5 | false" & wait $! | true
[1] 49493
-bash: wait: pid 49493 is not a child of this shell
hbaba@mbp-005063:~/misc$ echo $?
0
hbaba@mbp-005063:~/misc$ ps -T -f
UID PID PPID C STIME TTY TIME CMD
980771313 49493 69771 0 12:56AM ttys056 0:00.00 bash -c sleep 5 | false
980771313 49498 49493 0 12:56AM ttys056 0:00.00 sleep 5
0 49555 69771 0 12:56AM ttys056 0:00.01 ps -T -f
What is happening here?
I am using bash version GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
I can reproduce the wait error every time. I think it has something to do with each pipe being a separate subshell. https://unix.stackexchange.com/a/127346/212862
Maybe the wait $! command looks for the child process in the wrong shell.
The error message mentions the 49493 pid. That is indeed the right pid for the bash -c …
Command. The ps -T
shows that.
There are relevant questions q1 and q2. But in them there is no pipe usage after the wait
built-in.
Update
I had a misunderstanding about operator precedence in bash between the &
and |
. @randomir pointed that out in his answer. Adding curly braces makes the wait
wait on the previously backgrounded process. For example:
{ bash -c "sleep 5 | false" & wait $! ; } | true
This does not return the same wait error.