为什么不能反转 while 循环的输入重定向运算符的顺序?

为什么不能反转 while 循环的输入重定向运算符的顺序?

在 Bash 中,您可以将输入重定向运算符移至命令的前面:

cat <<< "hello"
# equivalent to
<<< "hello" cat

为什么你不能对 while 循环做同样的事情?

while read -r line; do echo "$line"; done <<< "hello"
# hello

<<< "hello" while read -r line; do echo "$line"; done
# -bash: syntax error near unexpected token `do'

我觉得有点令人困惑,因为你通过管道进入 while 循环。我做错了什么还是这只是一个设计决定?

答案1

这只是语法定义方式的结果。从POSIX Shell 语法规范:

command          : simple_command
                 | compound_command
                 | compound_command redirect_list
                 | function_definition
                 ;

和:

simple_command   : cmd_prefix cmd_word cmd_suffix
                 | cmd_prefix cmd_word
                 | cmd_prefix
                 | cmd_name cmd_suffix
                 | cmd_name
                 ;
[...]
cmd_prefix       :            io_redirect
                 | cmd_prefix io_redirect
                 |            ASSIGNMENT_WORD
                 | cmd_prefix ASSIGNMENT_WORD
                 ;
cmd_suffix       :            io_redirect
                 | cmd_suffix io_redirect
                 |            WORD
                 | cmd_suffix WORD
                 ;

可以看到,对于复合命令,只允许重定向,但是对于简单的命令,以前也是允许的。因此,当 shell 看到<redirection> foo,时,foo会被视为简单命令,而不是复合命令,并且while不再被视为关键字:

$ < foo while
bash: while: command not found

因此,这do是意想不到的,因为它只允许在某些关键字之后。

因此,这不仅适用于while循环,还适用于使用保留字设置复合命令的大多数方法:

$ < foo {
bash: {: command not found
$ < foo if
bash: if: command not found
$ < foo for
bash: for: command not found

相关内容