Jest to zależne od powłoki i nieudokumentowane AFAICS. W ksh
oraz bash
, w pierwszym przypadku, foo
będą dzielić to samo standardowe wejście bar
. Będą walczyć o produkcję echo
.
Na przykład w
$ seq 10000 | paste - <(tr 1 X)'
1 X
2 X042
3 X043
4 X044
5 X045
[...]
Widzisz dowody, które paste
czytają co drugi blok tekstu z seq
danych wyjściowych, podczas gdy tr
czytają pozostałe.
Za pomocą zsh
pobiera zewnętrzne wejście standardowe (chyba że jest to terminal, a powłoka nie jest interaktywna, w którym to przypadku jest przekierowywana /dev/null
). ksh
(skąd się wziął) zsh
i bash
są jedynymi powłokami podobnymi do Bourne'a z obsługą zastępowania procesów AFAIK.
W echo "bla" | bar < <(foo)
zauważyć, że bar
do standardowego wejścia będzie rura zasilany przez wyjście foo
. To dobrze określone zachowanie. W takim przypadku wydaje się, że foo
stdin jest rurą zasilaną przez echo
wszystkie ksh
, zsh
i bash
.
Jeśli chcesz zachować spójne zachowanie we wszystkich trzech powłokach i być przyszłościowym, ponieważ zachowanie może się zmienić, ponieważ nie jest udokumentowane, napisałbym to:
echo bla | { bar <(foo); }
Dla pewności foo
stdin jest także potokiem z echo
(nie rozumiem jednak, dlaczego chcesz to zrobić). Lub:
echo bla | bar <(foo < /dev/null)
Aby upewnić się, foo
że nie czyta z potoku z echo
. Lub:
{ echo bla | bar 3<&- <(foo <&3); } 3<&0
Aby mieć foo
standardowe wejście zewnętrzne, jak w obecnych wersjach zsh
.
echo "bla" | foo | bar
: Dane wyjścioweecho "bla"
są przekierowywane dofoo
, których dane wyjściowe są przekierowywanebar
.echo "bla" | bar <(foo)
: Ten potokuje wyjścieecho "bla"
dobar
. Alebar
jest wykonywany z argumentem. Argument jest ścieżką do deskryptora pliku, do którego dane wyjściowefoo
zostaną wysłane. Ten argument zachowuje się jak plik zawierający dane wyjściowefoo
. To nie to samo.echo "bla" | bar < <(foo)
: Można założyć, że dane wyjścioweecho "bla"
powinny być wysłane do,bar
a cała instrukcja jest równoważna z pierwszą. Ale to nie jest poprawne. Dzieje się tak: Ponieważ przekierowanie wejściowe<
jest wykonywane po potoku (|
), nadpisuje je . Więcecho "bla"
nie jest doprowadzony do baru. Zamiast tego wyjściefoo
jest przekierowywane jako standardowe wejście dobar
. Aby to wyczyścić, zobacz następujące polecenie i dane wyjściowe:Jak widzisz
echo "bla"
został zastąpiony przezecho "foo"
.Teraz zobacz to polecenie:
Więc
echo "bar"
jest przesyłany doawk
, który odczytuje stdin i dodaje ciągand foo
do wyniku. To wyjście jest przesyłane do potokucat
.źródło
awk
„ bar ”jest zdefiniowanym zachowaniem?cmd1 < <(cmd2)
zachowuje się tak samo jakcmd2 | cmd1
.cmd1 | cmd2 | cmd3
jest taki sam jakcmd1 | cmd3 < <(cmd2)