Answers:
那是壳依赖的,没有文档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,它将获得外部标准输入(除非它是一个终端,并且外壳不是交互式的,在这种情况下,它是从重定向的/dev/null)。ksh(起源于此),zsh并且bash是唯一支持流程替换AFAIK的类Bourne外壳。
在中echo "bla" | bar < <(foo),请注意,barstdin将是的输出馈送的管道foo。这是定义明确的行为。在这种情况下,似乎foo的标准输入是通过供给管echo中的所有的ksh,zsh和bash。
如果您希望在所有三个外壳上都具有一致的行为,并且要面向未来,因为该行为可能会因未记录而有所变化,请编写以下代码:
echo bla | { bar <(foo); }
为了确保foostdin也是管道echo(我看不出为什么要这么做)。要么:
echo bla | bar <(foo < /dev/null)
为了确保foo不会不从管道中读取echo。要么:
{ echo bla | bar 3<&- <(foo <&3); } 3<&0
要拥有foo标准输入,如外部版本的标准输入一样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,并且整个语句与第一个语句等效。但是,这是不正确的。发生以下情况:由于输入重定向<是在管道(|)之后执行的,因此它将覆盖它。因此echo "bla"不通过管道传输到酒吧。而是将的输出foo重定向为的标准输入bar。要清除此错误,请参见以下命令和输出:
$ echo "bla" | cat < <(echo "foo")
foo
如您所见echo "bla"被取代echo "foo"。
现在看到以下命令:
$ echo "bar" | cat < <(awk '{printf "%s and foo", $0}')
bar and foo
所以echo "bar"通过管道传递给awk,后者读取stdin并将字符串添加and foo到输出中。此输出通过管道传输到cat。
awk读“条” 的事实是否是已定义的行为?”
cmd1 < <(cmd2)的行为与相同cmd2 | cmd1。
cmd1 | cmd2 | cmd3等于cmd1 | cmd3 < <(cmd2)