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... 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. Commented Mar 16, 2017 at 14:15

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.