bash/zsh输入进程替换与while一起给出了语法错误

Mik*_*her 6 bash zsh

这些工作正常并做他们应该做的事情(打印文件foo的内容):

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

但是这给了我zsh中的语法错误:

zsh$ while read line; do echo $line; done <(cat foo)
zsh: parse error near `<(cat foo)'
Run Code Online (Sandbox Code Playgroud)

和bash:

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

有人知道原因,也许是一种解决方法吗?

注意:这显然是一个玩具示例.在真正的代码中,我需要在主shell进程中执行while循环的主体,所以我不能只使用

cat foo | while read line; do echo $line; done
Run Code Online (Sandbox Code Playgroud)

gle*_*man 7

您需要将进程替换重定向到while循环:

你写了

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

你需要

while read line; do echo $line; done < <(cat foo)
# ...................................^
Run Code Online (Sandbox Code Playgroud)

像文件名一样处理进程替换.


oli*_*bre 5

bash/ zsh替换<(cat foo)为具有名称的管道(文件类型),/dev/fd/n其中n是文件描述符(编号).

您可以使用该命令检查管道名称echo <(cat foo).

您可能知道,bash/ zsh也在cat foo另一个进程中运行该命令.第二个进程的输出将写入该命名管道.

没有过程替换:

while ... do ... done   inputfile #error
while ... do ... done < inputfile #correct
Run Code Online (Sandbox Code Playgroud)

使用流程替换的相同规则:

while ... do ... done   <(cat foo) #error
while ... do ... done < <(cat foo) #correct
Run Code Online (Sandbox Code Playgroud)

替代方案:

cat foo >3 & while read line; do echo $line; done <3;
Run Code Online (Sandbox Code Playgroud)