while 루프에 대해 입력 리디렉션 연산자의 순서를 반대로 바꿀 수없는 이유는 무엇입니까?


11

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 루프로 파이프 할 있기 때문에 약간 혼란 스럽습니다 . 내가 잘못하고 있거나 단지 디자인 결정 이었습니까?

답변:


16

그것은 문법이 어떻게 정의 되었는가에 따른 결과입니다. 에서 는 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

좋은 설명 감사합니다.
philraj
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.