Bash의 파이프(|) 및 논리 AND(&&) 우선순위

Bash의 파이프(|) 및 논리 AND(&&) 우선순위

연산자 우선 순위가 있는 클래식 시나리오에는 다음과 같은 줄이 있습니다.

(cd ~/screenshots/ && ls screenshot* | head -n 5)

그리고 그것이 파싱되었는지 ((A && B) | C)아니면 (A && B | C)...

이것거의 공식 문서확립된여기파이프가 목록에 나열되지 않아 간단히 테이블에 체크인할 수는 없습니다.

게다가 bash에서는 (작업 순서를 변경할 수 있을 뿐만 아니라 다음과 같은 작업도 수행할 수 있습니다.서브셸 만들기이므로 이 줄이 이전 줄과 동일하다고 100% 확신할 수는 없습니다.

((cd ~/screenshots/ && ls screenshot*) | head -n 5)

더 일반적으로 아는 방법아스파르테이트 아미노전이효소배쉬 알았어? Python에는 작업 순서를 쉽게 다시 확인할 수 있도록 트리를 제공하는 함수가 있습니다.

답변1

cd ~/screenshots/ && ls screenshot* | head -n 5

이는 다음과 같습니다.

cd ~/screenshots && { ls screenshot* | head -n 5 ; }

(이것중괄호는 명령을 함께 그룹화하므로 하위 쉘이 필요하지 않습니다.). 따라서 우선순위 는 .(더 단단하게 바인딩됨)의 우선순위 |보다 높습니다 . 그건,&&||

A && B | C

그리고

A || B | C

항상 의미B에서 C로의 출력만 제공. 필요한 경우 명령을 단일 엔터티로 함께 사용하거나 연결하여 명확하게 (...)할 수 있습니다.{ ... ; }

{ A && B ; } | C
A && { B | C ; } # This is the default, but you might sometimes want to be explicit

몇 가지 다른 명령을 사용하여 이를 테스트할 수 있습니다. 당신이 달리면

echo hello && echo world | tr a-z A-Z

그러면 당신은 얻을 것이다

hello
WORLD

뒤쪽에:tr a-z A-Z대문자로 입력하세요echo world, 파이핑 만 하면 스스로 통과하는 것을 볼 수 있습니다 echo hello.


이것에 정의됨쉘 구문, 매우 명확하지는 않지만 and_or생산( &&/ 에 대한)은 본문에 aa가 있고 만 포함 ||하도록 정의됩니다 .pipelinepipelinecommand아니요포함 and_or- complete_command프로덕션에만 도달할 수 and_or있으며 최상위 수준과 함수 및 루프와 같은 구조적 구성 내부에만 존재합니다.

이 구문을 수동으로 적용하여 명령의 구문 분석 트리를 얻을 수 있지만 Bash 자체는 어떤 것도 제공하지 않습니다. 나는 스스로 구문 분석하는 것 이상의 기능을 수행하는 쉘을 모릅니다.

셸 구문에는 준공식적으로만 정의되는 특수한 경우가 많이 있으며 이를 올바르게 정의하는 것은 어려운 작업이 될 수 있습니다. Bash 자체도가끔은 틀리기도 해이므로 실제 상황과 이상적인 상황은 다를 수 있습니다.

문법을 일치시키고 트리를 생성하는 외부 파서가 있습니다. 저는 이러한 외부 파서를 널리 권장합니다.모빅, 가장 신뢰할 수 있는 사람이 되려고 노력합니다.

답변2

긴 이야기 짧게;: , , 등의 구분 기호를 나열 하고 구문 분석 순서를 결정합니다 &.&&||

이것배쉬 매뉴얼우리에게 말해주세요:

AND 및 OR 목록은 하나 이상의 시퀀스입니다.관로제어 연산자를 && 및 ||로 구분하세요.

아니면 어떻게배쉬 해커의 위키일반적인 말하기

<PIPELINE1> && <PIPELINE2>

cd ~/screenshots/ && ls screenshot* | head -n 5 파이프 ls screenshot* | head -n 5와 간단한 명령이 있습니다 cd ~/screenshots/. 지시사항에 주의하세요

파이프라인의 각 명령은 별도의 프로세스(즉, 하위 셸에서)로 실행됩니다.

반면에 (cd ~/screenshots/ && ls screenshot*) | head -n 5다릅니다. 파이프라인이 있습니다. 왼쪽에는 서브쉘이 있고 오른쪽에는 서브쉘이 있습니다 head -n 5. 이 경우 OP 표기법을 사용하면 다음과 같습니다.(A && B) | C


또 다른 예를 들어보겠습니다:

$ echo foo | false &&  echo 123 | tr 2 5
$

여기에 목록이 있습니다 <pipeline1> && <pipeline2>. 파이프라인의 종료 상태가 마지막 명령과 동일하고 false부정적인 상태(즉, 실패)를 반환한다는 것을 알고 있으므로 &&오른쪽은 실행되지 않습니다.

$ echo foo | true &&  echo 123 | tr 2 5
153

여기서 왼쪽 파이프는 성공적인 종료 상태이므로 오른쪽 파이프가 실행되고 출력이 표시됩니다.


셸 구문은 실제 실행 순서를 의미하지 않습니다. 그 중 하나를 인용해 보세요자일스의 대답:

파이프라인 명령이 동시에 실행됩니다. ps | grep ...을 실행할 때 ps 또는 grep이 먼저 시작되는지 여부는 운의 문제입니다(또는 쉘 작업의 세부 사항과 커널 내부 스케줄러의 미세 조정의 문제). 어쨌든 그들은 계속됩니다.

Bash 매뉴얼에서:

AND 및 OR 목록은 왼쪽 연관성으로 수행됩니다.

이를 기반으로 cd ~/screenshots/ && ls screenshot* | head -n 5이전 명령이 성공하면 cd ~/screenshots/먼저 실행되지만 파이프라인에 있기 때문이 아니라 아마도 첫 번째 프로세스가 생성되었을 것입니다.ls screenshot* | head -n 5head -n 5ls

답변3

이는 다음에 지정된 위치입니다 bash(1).

SHELL GRAMMAR
[...]
   Pipelines
       A  pipeline  is  a sequence of one or more commands separated by one of
       the control operators | or |&.
[...]
   Lists
       A list is a sequence of one or more pipelines separated by one  of  the
       operators ;, &, &&, or ||, and optionally terminated by one of ;, &, or
       <newline>.

그러므로 &&배관을 분리하십시오.

답변4

당신은 시도 할 수 있습니다 echo hello && echo world | less. 우선 순위가 더 높은 것을 볼 수 있습니다 |(명령 파이프라인은 명령입니다). 두 번째 예는아니요같은. 그러나 cd출력이 없으므로 미묘한 차이는 없습니다.

관련 정보