Это зависит от оболочки и не документировано AFAICS. В ksh
и bash
, в первом случае, foo
будет использоваться тот же stdin, что и bar
. Они будут бороться за выход echo
.
Так, например, в
$ seq 10000 | paste - <(tr 1 X)'
1 X
2 X042
3 X043
4 X044
5 X045
[...]
Вы видите свидетельство, которое paste
читает каждый второй блок текста из seq
выходных данных, в то время как tr
читает другие.
С помощью zsh
он получает внешний stdin (если только он не является терминалом и оболочка не является интерактивной, и в этом случае она перенаправляется /dev/null
). ksh
(где он возник), zsh
и bash
являются единственными Bourne-подобными оболочками с поддержкой процесса замены AFAIK.
В echo "bla" | bar < <(foo)
, заметим , что bar
STDIN «S будет труба подается на выходной сигнал foo
. Это хорошо определенное поведение. В этом случае, похоже, что foo
stdin - это канал, которым питаются echo
все ksh
, zsh
и bash
.
Если вы хотите иметь согласованное поведение во всех трех оболочках и быть ориентированными на будущее, поскольку поведение может измениться, поскольку оно не задокументировано, я написал бы это:
echo bla | { bar <(foo); }
Чтобы быть уверенным, что foo
stdin - это еще и канал echo
(хотя я не понимаю, почему вы хотите это сделать). Или:
echo bla | bar <(foo < /dev/null)
Для того, чтобы убедиться , что foo
ничего не читать из трубы с echo
. Или:
{ echo bla | bar 3<&- <(foo <&3); } 3<&0
Иметь foo
's stdin' внешний stdin, как в текущих версиях zsh
.
echo "bla" | foo | bar
: Выходecho "bla"
перенаправлен наfoo
, чей выход перенаправлен наbar
.echo "bla" | bar <(foo)
Тот, кто передает выводecho "bla"
вbar
. Ноbar
выполняется с аргументом. Аргумент - это путь к дескриптору файла, кудаfoo
будет отправлен вывод . Этот аргумент ведет себя как файл, который содержит выходные данныеfoo
. Так что это не то же самое.echo "bla" | bar < <(foo)
: Можно предположить, что выходные данныеecho "bla"
должны быть отправлены,bar
и весь оператор эквивалентен первому. Но это не правильно. Происходит следующее: поскольку перенаправление ввода<
выполняется после pipe (|
), оно перезаписывает его . Такecho "bla"
что не пускай в бар. Вместо этого выводfoo
перенаправляется как стандартный ввод вbar
. Чтобы очистить это, смотрите следующую команду и вывод:Как видите
echo "bla"
, вытесняетсяecho "foo"
.Теперь посмотрим на эту команду:
Так
echo "bar"
что по каналуawk
, который читает стандартный ввод и добавляет строкуand foo
к выводу. Этот вывод передается по каналуcat
.источник
awk
читает« бар »определенное поведение?»cmd1 < <(cmd2)
ведет себя так же, какcmd2 | cmd1
.cmd1 | cmd2 | cmd3
же, какcmd1 | cmd3 < <(cmd2)