리디렉션은 명령 목록과 어떻게 상호 작용합니까?

리디렉션은 명령 목록과 어떻게 상호 작용합니까?

대부분의 사람들이 알고 있듯이 셸을 사용하면 명령을 실행할 때 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) 등이 될 수 있습니다.

분명히 "복합 명령"도 리디렉션될 수 있습니다. 복합 명령은 중괄호 그룹이나 하위 셸 또는 , , , 또는 명령문 { ...; }내의 파이프(단일 단순 명령일 수도 있음) 입니다.( ... )ifwhileforuntilcase

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)

관련 정보