Це лише наслідок того, як визначено граматику. З специфікації граматики оболонки 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