Ich hätte angenommen, dieser Code hätte ausgegeben "uff" Erste:
echo foo | tee >(rev) | ( sleep 1 ; cat ; )
Ausgabe:
foo
oof
Eine Verlängerung der sleep
Zeit ändert nichts an der Reihenfolge. Warum funktioniert das nicht?
Beachten Sie, dass andere WerkzeugeTunfunktioniert wie vorgesehen,z.B: echo foo | pee rev 'sleep 1 ; cat'
.
Antwort1
In
echo foo | tee >(rev) | (sleep 1; cat)
In bash
wie in ksh
, aber anders als bei zsh
, ist die Standardausgabe von rev
auch die Pipe zu (sleep 1; cat)
.
echo
, tee
, rev
und die (...)
Subshell werden gleichzeitig gestartet, tee
schreiben aber foo\n
nach stdoutVordie Pipe zu rev
, daher wird in jedem Fall nach den Schreibvorgängen in die Pipe rev
geschrieben , kann also nur zuletzt kommen. Verzögerungen haben keine Auswirkung.oof
tee
foo
oof
cat
Wenn Sie die Ausgabe vonrev
nichtum durch die Pipe zu zu gelangen (sleep 1; cat)
, verwenden zsh
oder tun Sie Folgendes:
{ echo foo 3>&- | tee >(rev >&3 3>&-) 3>&- | (sleep 1; cat) 3>&-; } 3>&1
Beachten Sie, dass in dieser Funktion zsh
auch eine Funktion integriert ist , mit der Sie Folgendes tun können:tee
multios
echo foo > >(rev) > >(sleep 1; cat)
Allerdings in:
echo foo > >(rev) | (sleep 1; cat)
Die Ausgabe rev
würde durchgehen cat
(was verwirrend ist, wenn man bedenkt, dass dies in diesem echo foo >(echo bar) | (sleep 1; cat)
Fall nicht der Fall ist).
Antwort2
Die Verwendung von zwei bash
Prozessersetzungen (anstatt nur einer und dann einer Pipe) und das anschließende Dumpen von STDOUT nach /dev/null funktioniert wie erwartet:
echo foo | tee >(rev) >( sleep 1 ; cat ; ) > /dev/null ; sleep 1
Ausgabe:
oof
foo
Anmerkungen:
- Die2. Platz
sleep
verhindert "foo" wird nach der Eingabeaufforderung gedruckt. - Es sollte besser sein , die
sleep
Verzögerungszahl auf ein Optimum zu reduzieren, aber ich bin nicht sicher, wie hoch diese Zahl sein sollte.1
ist etwas langsam, scheint aber immer zu funktionieren;.01
funktioniert nicht immer (d. h. die Ausgabe ist manchmal in der falschen Reihenfolge),.1
scheint gut zu funktionieren.