bash를 사용하면 표준 오류를 다른 프로세스에 어떻게 파이프 할 수 있습니까?


138

프로세스의 표준 출력을 다른 프로세스 표준 입력으로 파이프하는 방법은 잘 알려져 있습니다.

proc1 | proc2

그러나 proc1의 표준 오류를 proc2로 보내고 표준 출력을 현재 위치로 유지하려면 어떻게해야합니까? bash다음 줄을 따라 명령을 내릴 것이라고 생각합니다 .

proc1 2| proc2

그러나 아아, 아닙니다. 이것을 할 수있는 방법이 있습니까?


rc다른 쉘인 간단한 리디렉션을 수행 할 수 있습니다 . 예 : proc1 |[2] proc2. 멋지지 않습니까? bash하지만 그렇지 않습니다 .
Rolf

답변:


169

또한이 공정 대체 . 프로세스가 파일을 대체합니다. 다음과 같이 파일을
보낼 수 있습니다 stderr.

process1 2> file

그러나 다음과 같이 파일 프로세스를 대체 할 수 있습니다.

process1 2> >(process2)

다음은 stderr화면 모두에 보내고 로그 파일에 추가 하는 구체적인 예입니다.

sh myscript 2> >(tee -a errlog)

23
이것은 명시된 질문에 정확하게 답변하며 @paxdiablo의 답변이되어야합니다.
mmlb

나는 이것을 시도했다. 작동하지 않았고 ( weston --help 2> >(less)) 내 껍질이
Rolf

1
두 경우 @Rolf는 weston --helpless키보드 상호 작용을 가지고 있지만 그 중 하나가 수신하는 기대, 당신은 난처한 상황에있을 수 있습니다. grep대신 비슷한 방법으로 테스트 해보십시오 . 또한 마우스 / 키보드 입력이 모두 웨스턴이 아닌 두 번째 명령으로 이동하는 것을 알 수 있습니다.
BeowulfNode42

88

당신은에 다음과 같은 트릭을 사용할 수 있습니다 스왑 stdoutstderr. 그런 다음 일반 파이프 기능 만 사용하십시오.

( proc1 3>&1 1>&2- 2>&3- ) | proc2

처음에 동일한 장소를 제공 stdout하고 제공 stderr하면 필요한 것을 얻을 수 있습니다.

무엇 x>y비트가하는 일은 파일 핸들을 변경하는 것입니다 x지금 어디에 파일 핸들이 해당 정보 전송 있도록 y현재 포인트. 특정 사례의 경우 :

  • 3>&1아래의 마지막 글 머리 기호를 위해 어딘가에 저장 하기 위해 현재 핸들 (원래 stdout)에 출력 할 핸들 3을 만듭니다 .1
  • 1>&2핸들 1(stdout)을 수정 하여 현재 핸들 2(original stderr)로 출력합니다.
  • 2>&3-핸들 2(stderr)을 수정 하여 현재 핸들 3(원래 stdout )로 출력 한 다음 3( -끝을 통해) 핸들을 닫습니다 .

효과적으로 정렬 알고리즘에서 볼 수있는 swap 명령입니다.

temp   = value1;
value1 = value2;
value2 = temp;

3
1>&2-여기서 사용 하는 것보다 여기 에서 사용하는 것의 가치는 무엇입니까 1>&2? 2우리가 즉시 다시 열거 나 다시 할당 하려는 경우 fd를 닫고 싶은 이유를 이해할 수 없습니다 .
dubiousjim

1
@dubiousjim, 그 특별한 경우에는 이점이 없습니다. 파일 핸들 3을 닫는 것이 좋습니다.
paxdiablo

좋은 지적, @ovgolovin, 나는 편집 한 후 7 개월 만에 아무도 아무도 그것을 얻지 못했다고 믿을 수 없다. 귀하의 제안에 따라 수정되었습니다.
paxdiablo 2016 년

"(make 3> & 1 1> & 2- 2> & 3-) | less -R"gcc의 make (내 시스템에서 색상으로 표시됨)를 얻으려고 시도하는 반면 "(ls -al 3> & 1 1> & 2- 2> & 3-) | less -R "이 예상대로 작동합니다.
동기화되지 않음

두 번째 리디렉션에 대한 설명이 앞뒤로 표시되는 것 같습니다. 1> & 2-는 파일 핸들 2 (original stderr)를 1 (original stdout)로 처리하도록 설정하고 2> & 3-는 파일 핸들 3 (coded stdout)을 2 (original stderr)로 설정합니다. 그래도 틀렸다면 정정하십시오. btw, 2의 대시는 새 stderr 데이터가 stdout의 데이터로 채워지는 동안이 버퍼로 전송되는 것을 방지하는 것입니다.
aghsmith

70

Bash 4에는이 기능이 있습니다.

`| & '를 사용하면 command1의 표준 오류는 파이프를 통해 command2의 표준 입력에 연결됩니다. 2> & 1 |의 약어입니다. 표준 오류의 암시 적 리디렉션은 명령으로 지정된 리디렉션 후에 수행됩니다.

zsh에도이 기능이 있습니다.

-

다른 / 이전 쉘에서는 다음과 같이 명시 적으로 입력하십시오.

FirstCommand 2> & 1 | 다른 명령


14
문서를 읽음으로써 stderr과 달리 표준 오류 출력을 모두 수행 하지만 알아 두는 것이 좋습니다. bash 4를 볼 시간입니다.
paxdiablo

현재 bash 매뉴얼은 "| &를 사용하면 표준 출력과 함께 명령의 표준 오류 가 command2의 표준 입력에 연결됩니다 "라고 읽습니다 . 이것은 OP가 원하는 것이 아닙니다.
피터-복원 모니카

@ PeterA.Schneider : OP는 "표준 출력을 현재 위치로 남겨두고"모호 할 수 있다고 말합니다.
추후 공지가있을 때까지 일시 중지되었습니다.

나는 모호성을 보지 못했습니다. 당신의 제안 (1) 은 두 개의 흐름을 flat니다 . (2) 결합 된 데이터를 어딘가에, 아마도 다른 곳에 OtherCommand씁니다 . 따라서 동일한 데이터가 아니며 다른 곳으로 갈 가능성이 있습니다. 그것은 OP의 희망과 반대되는 것입니다.
피터-복원 모니카

@ PeterA.Schneider : 표준 출력의 현재 위치는 어디에 있습니까? 경우 proc1표준 출력과 표준 에러로 출력하고 사용자가 표준 에러가의 표준 입력에 가고 싶다 proc2(PROC1의 표준 출력이가는 곳이다), 그 다음 내 대답은을 수행합니다. 나는 그가 무엇 OP 준 물었다 그는 아마하지 무엇을, 의미 를 요청합니다. 그 안에 잠재적 인 모호성이 있습니다. 영업 이익은 답변을 받아 스왑이 되는 표준 출력 및 표준 오류 없는 그가 요구 무엇을.
추후 공지가있을 때까지 일시 중지되었습니다.

27

스와핑은 문제를 해결하므로 훌륭합니다. 원래 stdout이 필요하지 않은 경우 다음과 같이 할 수 있습니다.

proc1 2>&1 1>/dev/null | proc2

순서는 매우 중요합니다. 당신은 원하지 않을 것입니다 :

proc1 >/dev/null 2>&1 | proc1

이것으로 모든 것을 리디렉션합니다 /dev/null!


0

이들 중 어느 것도 실제로 잘 작동하지 않았습니다. 내가 찾은 가장 좋은 방법은 다음과 같습니다.

(command < input > output) 2>&1 | less

command키보드 입력이 필요하지 않은 경우에만 작동합니다 . 예 :

(gzip -d < file.gz > file) 2>&1 | less

gzip 오류를 덜 넣을 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.