这些工作正常并做他们应该做的事情(打印文件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)
您需要将进程替换重定向到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)
像文件名一样处理进程替换.
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)