为什么进程替换并不总是与bash中的while循环一起使用?

Joh*_*ith 10 bash process substitution while-loop

进程替换工作与文件名细,比如他们都

$ cat <FILENAME
Run Code Online (Sandbox Code Playgroud)

$ while read i; do echo $i; done <FILENAME
Run Code Online (Sandbox Code Playgroud)

工作.

但是如果我们使用echo命令(或任何其他生成输出到stdout的命令)而不是FILENAME ,则cat继续工作

$ cat <(echo XXX)
XXX
Run Code Online (Sandbox Code Playgroud)

而循环

$ while read i; do echo $i; done <(echo XXX) 
bash: syntax error near unexpected token `<(echo XXX)'
Run Code Online (Sandbox Code Playgroud)

产生错误.

有什么想法吗?

ric*_*ici 25

注:不是进程替换.这是一个重定向.进程替换具有格式.<filename<(command)

进程替换替换的过程的名称<(...).尽管使用了<符号,但它不是重定向.

所以当你说cat <(echo foo),bash创建一个子进程来运行echo命令,并替换可以读取的伪文件的名称来获取该命令的输出.替换的结果将是这样的:

cat /dev/fd/63
Run Code Online (Sandbox Code Playgroud)

请注意,没有重定向.(您可以通过键入来查看此操作echo <(echo foo).)

像许多实用程序一样,cat可以使用或不使用命令行参数调用; 如果没有指定文件,则从中读取stdin.所以cat file.txt并且cat < file.txt非常相似.

但该while命令不接受其他参数.所以

while read -r line; do echo "$line"; done < file.txt 
Run Code Online (Sandbox Code Playgroud)

是有效的,但是

while read -r line; do echo "$line"; done file.txt
Run Code Online (Sandbox Code Playgroud)

是语法错误.

流程替换不会改变这一点.所以

while read -r line; do echo "$line"; done /dev/fd/63
Run Code Online (Sandbox Code Playgroud)

是语法错误,因此也是如此

while read -r line; do echo "$line"; done <(echo foo)
Run Code Online (Sandbox Code Playgroud)

要指定进程替换的重定向,您需要重定向:

while read -r line; do echo "$line"; done < <(echo foo)
Run Code Online (Sandbox Code Playgroud)

请注意,两个<符号之间必须有空格,以避免与"here-doc"语法混淆<<word.