Das ist shellabhängig und nicht AFAICS dokumentiert. In ksh
und teilen sich bash
im ersten Fall foo
die gleichen Werte wie bar
. Sie werden für die Ausgabe von kämpfen echo
.
So zum Beispiel in,
$ seq 10000 | paste - <(tr 1 X)'
1 X
2 X042
3 X043
4 X044
5 X045
[...]
Sie sehen Beweise, paste
die jeden anderen Textblock aus seq
der Ausgabe tr
lesen, während die anderen gelesen werden.
Mit zsh
ruft es das äußere stdin ab (es sei denn, es ist ein Terminal und die Shell ist nicht interaktiv. In diesem Fall wird sie umgeleitet von /dev/null
). ksh
(woher es stammt) zsh
und bash
sind die einzigen Bourne-ähnlichen Shells mit Unterstützung für die Prozesssubstitution AFAIK.
In zu echo "bla" | bar < <(foo)
beachten , dass bar
s stdin wird das Rohr durch den Ausgang der gespeist werden foo
. Das ist gut definiertes Verhalten. In diesem Fall scheint es so, foo
als sei stdin die Pfeife, von der echo
in all ksh
, zsh
und gespeist wird bash
.
Wenn Sie ein konsistentes Verhalten für alle drei Shells haben und zukunftssicher sein möchten, da sich das Verhalten möglicherweise ändert, da es nicht dokumentiert ist, würde ich Folgendes schreiben:
echo bla | { bar <(foo); }
Um sicher zu gehen foo
, ist stdin auch die Pipe von echo
(ich kann nicht verstehen, warum du das machen möchtest). Oder:
echo bla | bar <(foo < /dev/null)
Um sicherzustellen , dass foo
sie nicht aus dem Rohr aus lesen echo
. Oder:
{ echo bla | bar 3<&- <(foo <&3); } 3<&0
Um foo
's stdin das äußere stdin wie in aktuellen Versionen von zu haben zsh
.
echo "bla" | foo | bar
: Die Ausgabe vonecho "bla"
wird an umgeleitetfoo
, deren Ausgabe an umgeleitet wirdbar
.echo "bla" | bar <(foo)
: Das leitet die Ausgabe vonecho "bla"
anbar
. Wirdbar
aber mit einem Argument ausgeführt. Das Argument ist der Pfad zum Dateideskriptor, an den die Ausgabe vonfoo
gesendet wird. Dieses Argument verhält sich wie eine Datei, die die Ausgabe von enthältfoo
. Das ist also nicht dasselbe.echo "bla" | bar < <(foo)
: Man kann davon ausgehen, dass die Ausgabe von anecho "bla"
gesendet werden sollbar
und die gesamte Anweisung der ersten entspricht. Aber das ist nicht richtig. Folgendes passiert: Da die Eingabeumleitung<
nach der Pipe (|
) ausgeführt wird, wird sie überschrieben . Istecho "bla"
also nicht zur Stange geleitet. Stattdessen wird die Ausgabe vonfoo
als Standardeingabe an umgeleitetbar
. Um dies zu beheben, lesen Sie den folgenden Befehl und die Ausgabe:Wie Sie sehen,
echo "bla"
wird durch abgelöstecho "foo"
.Sehen Sie sich nun diesen Befehl an:
Also
echo "bar"
wird an weitergeleitetawk
, was stdin liest und den Stringand foo
zur Ausgabe hinzufügt . Dieser Ausgang wird weitergeleitetcat
.quelle
awk
" bar "lautet, ein definiertes Verhalten?"cmd1 < <(cmd2)
verhält sich genauso wiecmd2 | cmd1
.cmd1 | cmd2 | cmd3
ist das gleiche wiecmd1 | cmd3 < <(cmd2)