대부분의 사람들이 알고 있듯이 셸을 사용하면 명령을 실행할 때 stdin/stdout/stderr을 리디렉션할 수 있으며 한 명령에서 다른 명령으로 출력을 파이프할 수도 있습니다.
연산자를 사용하여 조건부 또는 무조건적으로 차례로 실행되는 명령의 "목록"을 작성할 수 있다는 것을 아는 사람은 거의 없습니다 ;
&&
||
.
이러한 기능은 어떻게 상호 작용합니까? 내가 뭔가를하면
command1 && command2 >file
마지막 명령의 출력만 리디렉션합니까, 아니면 둘 다입니까? 내가 쓴다면
command1 | command2 && command3 | command4
실제로는 무엇을 합니까? 이 두 파이프에 조건이 있나요? 아니면 파이프라인인가포함하다파이프라인 단계 중 하나인 조건은 무엇입니까?
내가 아는 한, 쉘은 명확성을 위해 괄호를 추가하는 것을 지원하지 않으므로 어떻게 해석을 요청할 수 있는지 잘 모르겠습니다... 어쨌든 쉘이 이 모든 것을 어떻게 해석하는지 아는 것이 도움이 될 것입니다. . (대부분의 사람들처럼 저는 Bash만 사용합니다.)
답변1
지휘 중
command1 && command2 >file
출력은 command1
리디렉션되지 않지만 출력은 다음 command2
과 같습니다.
$ echo hello && echo ok >file
hello
$ cat file
ok
리디렉션은 command1
개별적으로 수행할 수 있습니다.
command1 >file1 && command2 >file2
지휘 중
command1 | command2 && command3 | command4
의 출력은 command1
으로 파이프됩니다 command2
. 첫 번째 파이프가 종료 상태 0으로 종료되면 두 번째 파이프도 비슷한 방식으로 실행됩니다.
$ echo hello | cat && echo bye | cat
hello
bye
command2 && command3
목록을 그룹화하려면 다음과 같이 작성하십시오 .
command1 | { command2 && command3; } | command4
이는 출력이 command1
복합 명령으로 파이프됨을 의미합니다 command2 && command3
. 그런 다음 복합 명령의 출력이 다음으로 파이프됩니다 command4
.
$ echo hello | { read message && printf 'We got "%s"\n' "$message"; } | rev
"olleh" tog eW
단일 단순 명령(아래 참조)을 리디렉션할 수 있습니다.
$ echo hello | { read message && printf 'We got "%s"\n' "$message"; echo bye >&2; } | rev
bye
"olleh" tog eW
&&
셸 구문에서 "완전한 명령"은 또는 로 구분된 일련의 파이프로 구성됩니다 ||
. 이것은매우 느슨하다말하기. 이는 과 가 &&
파이프라인에서 보다 ||
더 높은 우선순위를 갖는다는 것을 의미합니다.|
반면에 리디렉션은 구문이 "간단한 명령" 구성의 리디렉션 부분을 만들기 때문에 현재 명령과 긴밀하게 통합됩니다. 간단한 명령은 일부 명령 접두사, 명령 이름 및 명령 접미사(접두사와 접미사는 선택 사항임)입니다. 명령 접두사는 환경 변수에 대한 할당( VAR=value myscript
) 또는 리디렉션( >outfile cat
)일 수 있습니다. 마찬가지로 명령 접미사는 리디렉션( cat >outfile
) 등이 될 수 있습니다.
분명히 "복합 명령"도 리디렉션될 수 있습니다. 복합 명령은 중괄호 그룹이나 하위 셸 또는 , , , 또는 명령문 { ...; }
내의 파이프(단일 단순 명령일 수도 있음) 입니다.( ... )
if
while
for
until
case
POSIX 셸(및 bash
확장)의 전체 구문은 POSIX 표준에서 찾을 수 있습니다. 다음은 구문 규칙의 최상위 수준입니다.
program : linebreak complete_commands linebreak
| linebreak
;
complete_commands: complete_commands newline_list complete_command
| complete_command
;
complete_command : list separator_op
| list
;
list : list separator_op and_or
| and_or
;
and_or : pipeline
| and_or AND_IF linebreak pipeline
| and_or OR_IF linebreak pipeline
;
pipeline : pipe_sequence
| Bang pipe_sequence
;
pipe_sequence : command
| pipe_sequence '|' linebreak command
(인용하다:https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_10_02)