그냥 호기심,
이 명령의 작동 방식:
$ <file cat
그러나 다음 중 어느 것도 없습니다:
$ <file for
bash: for: command not found...
$ <file while
bash: while: command not found...
왜 그런 겁니까?
답변1
이것POSIX 구문이렇게 쓰여 있습니다. 명령은 다음과 같이 정의됩니다.
command : simple_command
| compound_command
| compound_command redirect_list
| function_definition
간단한 명령은 어디에 있습니까?
simple_command : cmd_prefix cmd_word cmd_suffix
[...]
둘 다 cmd_prefix
결국 cmd_suffix
리디렉션을 허용합니다. 복합 명령의 경우 redirect_list
이를 허용하는 선행 명령 없이 끝에서만 허용됩니다.
좀 빠지는가지다예를 들어 Zsh는 이것을 잘 받아들입니다:
% > output for x in a b c ; do echo $x; done
% cat output
a
b
c
그러나 이것은 Zsh와 호환되지 않습니다. 왜냐하면 표준 쉘에서 선행 리디렉션으로 인해 명령이 for
일반 단순 명령으로 구문 분석되기 때문입니다. 즉, 다음은 다음과 같습니다.효과적인쉘은 문자 그대로 호출되는 명령을 찾아서 실행하려고 시도합니다 for
(인수 5개 및 stdout 리디렉션 포함). 오류가 발생하면 다음이 표시됩니다.
$ > output for x in a b c
bash: for: command not found
(구체적으로 Bash에서는 전체 입력 줄이 먼저 구문 분석되므로 for-do-done
첫 번째 예제의 전체 항목을 Bash에 공급하면 에 대한 구문 오류만 제거되고 이전 항목은 do
실행되지 않습니다 .)for
추측해야 한다면 이 정의의 근본적인 이유는 항상 이런 식으로 작동했기 때문에 표준에서 그렇게 인코딩했기 때문이라고 예상합니다.
비록논의하다이 분야의 표준 변경에 관해. (아마도 올바른 마음을 가진 사람 중 실제로 쉘 루프가 아닌 > output for ...
명령 호출의 의미 에 의존하는 사람은 없을 것입니다.)for
답변2
for
명령이 아니며 while
루프 헤더를 시작하는 예약어입니다. 전체 루프에 대해 리디렉션을 사용할 수 있지만 리디렉션은 끝에 있어야 합니다.
이것은 실제로아니요일하다:
<file for((i=0;i<3;i++)); do read line; echo "$line"; done
이것하다일하다:
for((i=0;i<3;i++)); do read line; echo "$line"; done <file