Bash
為什麼不能顛倒 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 循環。我做錯了什麼還是只是一個設計決定?
這只是語法定義的結果。從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