Bash

為什麼不能顛倒 while 循環的輸入重定向運算符的順序?

  • August 26, 2019

在 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 循環。我做錯了什麼還是只是一個設計決定?

這只是語法定義的結果。從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

引用自:https://unix.stackexchange.com/questions/537408