11

I pipe the same content to multiple commands with tee, redirects and process substitution subshells like this:

#!/usr/bin/env bash

echo 'hello' | tee \
  >( sleep 3; cat /dev/stdin ) \
  >( sleep 2; cat /dev/stdin ) \
  >( sleep 1; cat /dev/stdin )

wait # Doesn't work :(

However, what I see is that the process substitution subshell output is written to the terminal after the main script exits and wait doesn't work:

$ ./test.sh
hello
$ hello
hello
hello

How to properly wait for the process substitution subshells?

2
  • I think this isn't possible. You'd need to capture the PIDs of each subshell, but process substitution will never give them to you. I will be fascinated to see if there is a simple solution though. Commented Mar 16, 2017 at 3:56
  • @MichaelHomer Apparently zsh is wait-ing for the children...
    – heemayl
    Commented Mar 16, 2017 at 4:07

1 Answer 1

8

In bash, you can't wait for process substitution. In:

cmd1 > >(cmd2)

the whole command finish as soon as cmd1 finish, regardless the status of cmd2.

You have to implement a mechanism to signal the parent process that the cmd2 have finished. An easy way, using a fifo:

#!/usr/bin/env bash

trap 'rm wait.fifo' EXIT
mkfifo wait.fifo

echo 'hello' | tee \
  >( sleep 3; cat /dev/stdin; : >wait.fifo ) \
  >( sleep 2; cat /dev/stdin; : >wait.fifo ) \
  >( sleep 1; cat /dev/stdin; : >wait.fifo )

for (( i=0;i<3;i++ )); do read <wait.fifo; done
1
  • Works indeed, thanks! Although I ended up writing to a file and starting the commands separately.
    – serega
    Commented Mar 16, 2017 at 14:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .