これは、文法がどのように定義されているかの結果です。POSIXシェルの文法仕様:
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
;
ご覧のとおり、複合コマンドではリダイレクトはの後にのみ許可されますが、単純なコマンドではリダイレクトも前に許可されます。したがって、シェルがを見る<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