/ / Bash Umleitung von stdio auf Named Pipes - bash, asynchron, pipe, Named-Pipes

Bash, das stdio auf Named Pipes umleitet - bash, asynchron, pipe, named-pipes

Ich habe ein paar Prozesse, die laufenasynchron und jeder nimmt die Eingabe von einem FIFO und überträgt seine Ausgabe auf ein anderes FIFO. Ich möchte diese asynchron lesen. Das Problem ist, dass ich die Ausgabe nicht zu erhalten scheint, bevor das FIFO geschlossen ist. Hier ist ein Beispiel

#!/bin/bash -x

rm -rf /tmp/fifo[123].{in,out}
for i in $(seq 1 3) ; do
mkfifo /tmp/fifo$i.in
mkfifo /tmp/fifo$i.out
done

fin1=/tmp/fifo1.in
fout1=/tmp/fifo1.out

fin2=/tmp/fifo2.in
fout2=/tmp/fifo2.out

fin3=/tmp/fifo3.in
fout3=/tmp/fifo3.out

(echo "Proc 1"; while read var; do echo "proc1: " $var; done) < $fin1 > $fout1 &
(echo "Proc 2"; while read var; do echo "proc2: " $var; done) < $fin2 > $fout2 &
(echo "Proc 3"; while read var; do echo "proc3: " $var; done) < $fin3 > $fout3 &

# Get some of the output
cat $fout1 >> /tmp/test.before
cat $fout2 >> /tmp/test.before
cat $fout3 >> /tmp/test.before

# Generate more output
echo "Do you copy proc 1" > $fin1
echo "Do you copy proc 1" > $fin2
echo "Do you copy proc 1" > $fin3

# Get the rest of the output
cat $fout1 >> /tmp/test.after
cat $fout2 >> /tmp/test.after
cat $fout3 >> /tmp/test.after

# Show the results
echo "Before input:"
cat /tmp/test.before

echo "After input:"
cat /tmp/test.after

Was in ... resultiert

$ ./test.sh
+ rm -rf "/tmp/fifo[123].in" "/tmp/fifo[123].out"
++ seq 1 3
+ for i in "$(seq 1 3)"
+ mkfifo /tmp/fifo1.in
+ mkfifo /tmp/fifo1.out
+ for i in "$(seq 1 3)"
+ mkfifo /tmp/fifo2.in
+ mkfifo /tmp/fifo2.out
+ for i in "$(seq 1 3)"
+ mkfifo /tmp/fifo3.in
+ mkfifo /tmp/fifo3.out
+ fin1=/tmp/fifo1.in
+ fout1=/tmp/fifo1.out
+ fin2=/tmp/fifo2.in
+ fout2=/tmp/fifo2.out
+ fin3=/tmp/fifo3.in
+ fout3=/tmp/fifo3.out
+ cat /tmp/fifo1.out

Wie bekomme ich eine asynchrone Kommunikation? Ich möchte Koprozesse vermeiden, weil ich nicht im Voraus weiß, wie viele asynchrone Prozesse ich benötige und die Dinge unordentlich werden.

Antworten:

1 für die Antwort № 1

Folgende Zeile hinzufügen

for x in $fout1 $fout2 $fout3; do printf "" > $x & done

Unmittelbar vor dem Start scheinen die drei Unterprozesse den Deadlock zu durchbrechen. Ich bin mir nicht ganz sicher, warum. Wenn Sie die leere Zeichenfolge durch Text ersetzen, wird dieser Text erzeugt test.beforeIch vermute also, dass die gesamte Subshell nicht nur die beiliegende read, blockiert die E / A-Weiterleitungen.


0 für die Antwort № 2

Ich frage mich, warum Sie stdout und stderr Weiterleitungen außerhalb der Subshell setzen:

(echo "Proc 1"; while read var; do echo "proc1: " $var; done) < $fin1 > $fout1 &
(echo "Proc 2"; while read var; do echo "proc2: " $var; done) < $fin2 > $fout2 &
(echo "Proc 3"; while read var; do echo "proc3: " $var; done) < $fin3 > $fout3 &

IMHO sollte werden:

(echo "Proc 1" > $fout1; while read var; do echo "proc1: " $var; done < $fin1 >> $fout1) &
(echo "Proc 2" > $fout2; while read var; do echo "proc2: " $var; done < $fin2 >> $fout2) &
(echo "Proc 3" > $fout3; while read var; do echo "proc3: " $var; done < $fin3 >> $fout3) &
look here ^^^^^

Alle Prozesse, einschließlich Umleitungen, befinden sich also in einer Subshell, die vom Hauptprozess abgezweigt ist, und das Hauptskript blockiert beim ersten Zyklus nicht.