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

时间:2012-01-17 15:20:02

标签: bash zsh

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

cat <foo
while read line; do echo $line; done <foo
cat <(cat foo)

然而,这在zsh中给出了语法错误:

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

和bash:

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

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

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

cat foo | while read line; do echo $line; done

3 个答案:

答案 0 :(得分:7)

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

你写了

while read line; do echo $line; done <(cat foo)

你需要

while read line; do echo $line; done < <(cat foo)
# ...................................^

将进程替换视为文件名。

答案 1 :(得分: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

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

while ... do ... done   <(cat foo) #error
while ... do ... done < <(cat foo) #correct

<强>替代:

cat foo >3 & while read line; do echo $line; done <3;

答案 2 :(得分:2)

我建议只能解决这个问题:

theproc() { for((i=0;i<5;++i)) do echo $i; }

while read line ; do echo $line ; done <<<"$(theproc)"