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 쉘 구문 사양:

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

관련 정보