파이프 B를 D로? -A && B || C | 디


14

A && B || C | DB 또는 C가 D로 파이프되도록 명령 구조를 다시 쓰는 방법이 있습니까?

현재 명령을 사용하면 B 만 또는 C와 D가 모두 실행됩니다.

예를 들면 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

답변:


31

bash에서는 괄호를 사용할 수 있습니다.

(A && B || C) | D

이 방법으로의 출력 A && B || C이로 파이프됩니다 D.


6
또는 A && (B || C) | DA가 실패 할 때 B, C 또는 D를 실행하지 않으려면
zwol

2
당신은 또한에 parens를 사용할 수 있습니다 sh:)
EKons

중괄호 대신 괄호를 사용하는 것이 의도적 인 결정인지 (그렇다면 이점은 무엇입니까?) 아니면 단지 감독인지는 확실하지 않습니다. 설명해 주시겠습니까?
Tom Fenech

@TomFenech Parens는 하위 쉘에서 표현식이 실행되도록합니다. 서브 쉘은 나머지 스크립트의 POV와 (단일) 분리 된 프로세스입니다. 따라서 Parens 내부의 표현식 출력에 관계없이 함께 파이프됩니다. ( A서브 쉘 안에 있으므로 A
여기에도

1
@ jpaugh 격리에 대한 당신의 요점은 좋은 것이라고 생각하지만 중괄호를 사용할 때 출력이 같은 방식으로 파이프됩니다.
Tom Fenech

14

이것을 다음과 같이 쓸 수 있습니다

if A; then B; else C; fi | D

당신은 당신이 중 하나를 실행하고 싶은 말은 BC,하지만 A && B || C그것을 달성하지 않습니다. 경우 A, 그러나 성공 B실행 및 실패, 그것을 실행하는 것입니다 C.

참고 1 : B항상 성공하고 짧은 버전을 고수 한다고 보장 할 수 있다면 여전히 선택합니다.

{ A && B || C; } | D

이상 ( ... ), 또는 멀리 최적화되지 않을 수도 있습니다 새로운 서브 쉘이 생성 될 수있는 후자 불필요하게 힘으로.

참고 2 : 두 형식 모두 A출력을 생성하지 않는다고 가정 합니다. 이는 예제에서는 사실이지만 반드시 그렇지는 않습니다. 그것은 피할 수 있습니다

A; if [ "$?" -eq 0 ]; then B; else C; fi | D

당신은 반드시 그 계십니까 { … }파이프로 인해 생성 될 수있는 서브 쉘을 강제하지 않는 이유는 무엇입니까? 나는 다음과 같은 행동을 관찰 : pgrep bashpgrep bash | catif true; then pgrep bash; fi{ pgrep bash; }출력의 한 줄이있다; ( pgrep bash; )( pgrep bash; ) | cat{ pgrep bash; } | catif true; then pgrep bash; fi | cat출력의 두 라인을 갖는다.
wchargin

@wchargin ... | ...은 피할 수없는 서브 쉘을 생성합니다. ( ... )적어도 이론 상으로는 피할 수 있는 추가 서브 쉘이 만들어 { ...; }지지만 이것이 바로 "최적화되거나 최적화되지 않을 수 있습니다"라는 의미입니다. 효과는 동일합니다.
hvd

5

수락 자 답변은 정확하지만 의 입력으로 출력을 갖지 않는 잠재적 사용 사례를 다루지 않습니다 . 이를 위해서는 필요에 따라 스트림 리디렉션이 필요 합니다.ADA

  • A어쨌든 출력을 삭제하려면 다음을 수행하십시오.

    { A >/dev/null && B || C; } | D
  • A터미널 에서 출력을 보려면 :

    { A >/dev/tty && B || C; } | D
  • A후속 명령의 입력으로 의 출력 E이 필요한 경우 추가 명령 그룹과 스트림 리디렉션이 필요합니다.

    { { A >&3 && B || C; } | D; } 3>&1 | E

이 모든 것이 당신에게 너무 이상하게 보일 경우 (나처럼) 종료 상태에 특수 쉘 변수를 사용하고 그 작업을 수행하는 것이 좋습니다 A.

A
if [ $? -eq 0 ]; then
  B
else
  C
fi |
D

더 간결하고 싶지만 너무 간결하지 않으려면 다음과 같이 제안하십시오.

A; { [ $? -eq 0 ] && B || C; } | D

( 원래 답변을 쓸 때 눈치 채지 못한 hvd의 답변 의 마지막 부분도 참조하십시오 .)


내 대답은 그것을 다룹니다. A파이프 라인에서 단순히 나간 "참고 2 :"에 무엇을 넣었는지보십시오 .
hvd

@ hvd : 당신은 정확하고 나에게 당신의 대답의 일부를 지적 해 주셔서 감사합니다! 나는 나의 주장을 변경하고 그에 따라 신용을 주었다.
David Foerster
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.