배관 stdout없이 stderr를 배관하는 방법


24

표준 출력 스트림을 파이핑하지 않고 표준 오류 스트림을 어떻게 파이프합니까?

나는이 명령이 작동한다는 것을 알고 있지만 표준을 작성합니다.

Command 2>&1 | tee -a $LOG

표준 오류는 어떻게 받습니까?

참고 : 내가 원하는 것은 stderr 스트림을 로그에 쓰고 stderr과 stdout을 콘솔에 쓰는 것입니다.

답변:


26

이를 위해 하나의 추가 파일 설명자를 사용하여 stderr 및 stdout을 전환하십시오.

find /var/log 3>&1 1>&2 2>&3 | tee foo.file

기본적으로 다음과 같이 작동하거나 적어도 작동한다고 생각합니다
. 리디렉션은 왼쪽에서 오른쪽으로 평가됩니다.

3>&1 새 파일 디스크립터 3을 fd 1 (stdout)의 복제본 (복사본)으로 만듭니다.

1>&2 stdout (1)을 fd 2 (stderr)의 복제본으로 만듭니다.

2>&3 이전에 stdout의 사본으로 작성된 3의 사본 (복사) 인 fd 2를 작성하십시오.

이제 stderr과 stdout이 전환되었습니다.

| tee foo.file tee는 stderr로 작성된 파일 설명자 1을 복제합니다.


아, ksh로 테스트되지는 않았지만 bash와 함께 작동합니다.
Kyle Brandt

고마워, ksh에서도 작동합니다. 파이프와 스트림의 대부분은 posix 표준이라고 생각합니다.
C. Ross

"복사"가 실제로 정확하지 않습니다-@ Guasqueño의 답변을 참조하십시오.
Kyle Brandt

이것은 또한 tee.exe설치된 Windows에서 작동합니다 :)
Acorn

13

Kyle의 Unix / Linux 명령은 STDOUT으로 STDERR을 전환하는 작업을 수행합니다. 그러나 설명이 옳지 않습니다. 경로 재 지정 연산자는 복사 또는 복제를 수행하지 않고 플로우를 다른 방향으로 경로 재 지정합니다.

3> & 1을 임시로 끝까지 이동하여 Kyle의 명령을 다시 작성하면 개념을보다 쉽게 ​​이해할 수 있습니다.

find /var/log  1>&2  2>&3  3>&1  

이 방법으로 작성하면 Linux는 3> & 1 이전에있는 & 3이 아직 없기 때문에 오류를 표시합니다. 3> 무언가가 우리가 세 번째 파이프를 사용할 것이라고 선언 (정의)하는 방법이므로, 우리가 그 파이프로 물을 흘리기 전에 위치해야합니다 (예 : Kyle이 쓴 방식). 재미를 위해 다른 방법으로 시도하십시오.

((echo "STD1";  anyerror "bbbb"; echo "STD2" ) 3>&1 4>&2 1>&4 2>&3) > newSTDOUT 2> newSTDERR

사본을 만들 방법이 없다는 것은 부끄러운 일입니다. Linux는 첫 번째 명령 만 사용하고 두 번째 명령은 무시하므로 동일한 명령에서 "3> & 1 3> & 2"와 같은 작업을 수행 할 수 없습니다.

오류와 일반 출력을 모두 파일로 보내고 오류 복사본을 하나의 명령으로 표준 출력으로 보내는 방법을 찾지 못했습니다. 불안정하게하기 위해 두 출력 (오류 및 표준)이 로그 파일로 이동하고 오류가 나가서 blackBerry로 전자 메일 메시지를 보내도록하는 cron 작업이 있습니다. "tee"를 사용하여 두 개의 명령으로이를 수행 할 수 있지만 파일의 일반 출력 행 중에서 오류가 올바른 순서로 표시되지 않습니다. 이것이 내가 문제를 해결 한 못생긴 방법입니다.

((echo "STD1"; sdfr "bbbb"; echo "STD2" ) 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1

log1을 두 번 사용해야하고 두 경우 모두 "tee"명령에 대해 "-a"옵션을 사용하고, ">>"를 사용하여 두 번째를 추가해야합니다.

이렇게 고양이 로그 1 다음을 얻을 수를 :

STD1
STD2
-bash: sdfr: command not found

두 번째 줄에는 오류가 표시되지 않습니다.


굉장한 정정!
Kyle Brandt

FD를 여러 번 리디렉션 할 수 있도록 zsh 및 mult_ios옵션 (기본적으로 설정되어 있음)을 확인하십시오 .
Tom Hale

2

ksh (pdksh) 매뉴얼 페이지에 따르면 다음을 수행 할 수 있습니다.

명령 2> & 1> / dev / null | 고양이 -n

즉, dup stderr를 stdout으로, stdout을 / dev / null로 리디렉션 한 다음 'cat -n'으로 파이프

내 시스템의 pdksh에서 작동합니다.

$ errorecho () {echo "$ @"> & 2;}

$ errorecho foo
푸

$ errorecho foo> / dev / null #은 stdout이 리디렉션 된 경우에도 여전히 표시됩니다
푸

$ errorecho foo 2> & 1> / dev / null | 고양이 -n
     1 푸
$   

BusyBox와 함께 작동
Udo G

1

나는 또한 그것을 필요로했기 때문에 원하는대로 실행하고 명령을 수정했습니다. 이제 나를 위해 데비안 스퀴즈에서 bash 3.2를 사용하여 올바르게 작동합니다.

(echo "foo" 3>&1 1>&2 2>&3 | tee -a log1 ) 2>> log1 >> log2

반면 log1은 stdout과 stderr을 기록하고 log2는 stderr 만 기록하고 화면에 넣은 것은 기록하지 않습니다.

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