Warten Sie auf Bash-Subshells

7

Ich teeleite den gleichen Inhalt an mehrere Befehle mit Subshells und Weiterleitungen wie folgt weiter:

#!/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 :(

Ich sehe jedoch, dass die Subshell-Ausgabe nach dem Beenden des Hauptskripts in das Terminal geschrieben wird und waitnicht funktioniert:

$ ./test.sh
hello
$ hello
hello
hello

Wie kann man richtig auf die Subshells warten?

Serega
quelle
Ich denke das ist nicht möglich. Sie müssten die PIDs jeder Subshell erfassen, aber die Prozessersetzung wird sie Ihnen niemals geben. Ich werde fasziniert sein zu sehen, ob es eine einfache Lösung gibt.
Michael Homer
@ MichaelHomer Anscheinend zshist wait-ing für die Kinder ...
heemayl

Antworten:

7

In bashkönnen Sie nicht auf die Prozessersetzung warten. Im:

cmd1 > >(cmd2)

Der gesamte Befehl wird sofort cmd1beendet, unabhängig vom Status von cmd2.

Sie müssen einen Mechanismus implementieren, um dem übergeordneten Prozess zu signalisieren, dass der Vorgang cmd2abgeschlossen ist. Ein einfacher Weg mit einem 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
cuonglm
quelle
Funktioniert in der Tat, danke! Obwohl ich am Ende in eine Datei geschrieben und die Befehle separat gestartet habe.
Serega