我可以在复合命令之前指定重定向输入吗?

我可以在复合命令之前指定重定向输入吗?

Bash 允许您在命令之前指定重定向输入:

$ <lines sed 's/^/line: /g'
line: foo
line: bar

Bash 还允许您将输入重定向到复合命令,例如while循环:

$ while read line; do echo "line: $line"; done <lines
line: foo
line: bar

但是,当我尝试在循环之前指定重定向输入时while,出现语法错误:

$ <lines while read line; do echo "line: $line"; done
bash: syntax error near unexpected token `do'

这有什么问题吗?是否无法在 Bash 中的复合命令之前指定重定向输入?如果是这样,为什么不呢?

答案1

man bash说:

...重定向操作符可以出现在一个表达式中的任何位置之前或出现简单的命令或者可以遵循命令。

while不是一个简单的命令。

答案2

你可以在zsh,而不是在bashchoroba 已经向您指出了文档,但是如果您想之前进行重定向,您可以执行以下操作:

< file eval '
  while IFS= read -r line; do
    ...
  done'

或者(在支持 的系统上/dev/fd/n):

< file 3<< 'EOF' . /dev/fd/3
while IFS= read -r line; do
  ...
done
EOF

(这不是你想要做的)。

您还可以这样做:

exec 3< file
while IFS= read -r line <&3; do
  ...
done
exec 3<&-

(请注意,如果无法打开,exec将退出脚本)。file

或者使用一个函数:

process()
  while IFS= read -r line; do
    ...
  done

< file process

答案3

如果您想在输入之前使用该替换,则可以使用该替换:

cat lines | while read line; do echo "line: $line"; done

答案4

您可以使用 exec 重定向标准输入。

在脚本中:

exec < <(cat lines)
while read line ; do echo "line: $line"; done

不过,您不能在登录 shell 中使用(它会将文件转储到标准输出上并退出)。在这种情况下,您可以打开不同的文件描述符:

exec 3< <(cat lines)
while read -u 3 line ; do echo "line: $line"; done

以供参考:使用执行

相关内容