/ / Bash przekierowuje stdio do nazwanych potoków - bash, asynchronous, pipe, named-pipes

Bash przekierowuje stdio do nazwanych potoków - bash, asynchroniczny, pipe, named-pipes

Mam kilka procesów uruchomionychasynchronicznie, a każdy z nich pobiera dane wejściowe z fifo i wyświetla sygnał wyjściowy do innego fifo. Chcę je odczytać asynchronicznie. Problem polega na tym, że nie mogę uzyskać wyjścia przed zamknięciem fifo. Oto przykład

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

Co skutkuje w

$ ./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

Jak mogę uzyskać asynchroniczną komunikację w ten sposób? Chciałbym uniknąć koprocesów, ponieważ nie wiem z góry, ile procesów asynchronicznych będę potrzebować, a rzeczy będą się bałaganić.

Odpowiedzi:

1 dla odpowiedzi № 1

Dodawanie następującego wiersza

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

tuż przed rozpoczęciem trzech podprocesów zdaje się przełamać zakleszczenie. Nie jestem do końca pewien, dlaczego. Zastąpienie pustego łańcucha tekstem powoduje utworzenie tego tekstu test.before, więc podejrzewam, że cała podpowłoka, a nie tylko załączona read, blokuje przekierowania we / wy.


0 dla odpowiedzi nr 2

Zastanawiam się, dlaczego umieszczasz przekierowania stdout i stderr poza podpowłoką:

(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 Powinien stać się:

(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 ^^^^^

Zatem wszystkie procesy, w tym przekierowania, znajdują się w podpowłoce, która jest rozwidlona od głównego procesu, a główny skrypt nie będzie blokował się podczas pierwszego cyklu.