오류가 있는 경우 2>&1을 수행하고 다른 프로그램으로 파이프(|)합니다. 그렇지 않으면 2>&1을 수행하고 파이프하지 마십시오.
답변1
그래서 당신은 달리고 싶어
main_program 2>&1 | filter_program
그러나 filter_program
실패 상태가 반환되는 경우에만 실행해야 합니다.main_program
프로그램의 상태는 실행이 완료될 때까지 알 수 없습니다. 따라서 프로그램이 실패한 경우에만 출력을 처리하려면 프로그램이 실행되는 동안 프로그램의 출력을 저장했다가 프로그램이 완료된 후 출력 처리 명령을 실행하거나 출력을 폐기해야 합니다. 이 답변에서는 "출력"을 사용하여 stdout과 stderr의 결합된 출력을 의미합니다. stdout을 별도로 처리하려면 추가 작업이 필요할 수 있습니다.
출력이 작고 텍스트만 있는 경우 출력을 저장하고 쉘 변수에 상태를 반환할 수 있습니다. 대부분의 쉘은 변수에서 이진 데이터를 지원하지 않기 때문에 이진 데이터(널 바이트를 포함하는 데이터)에는 작동하지 않습니다.
error_output=$(main_program 2>&1; echo ".$?")
error_status=${error_output##*.}
error_output=${error_output%.*}
if [ "$error_status" -ne 0 ]; then
printf %s "$error_output" | filter_program
fi
출력이 크거나 바이너리일 가능성이 높으면 임시 파일에 저장하세요.
output_file=$(mktemp)
main_program >"$output_file" 2>&1
if [ "$?" -ne 0 ]; then
filter_program <"$output_file"
fi
rm -f -- "$output_file"
(생략: 신호의 임시 파일을 삭제하는 코드입니다.)
(입력이 파이프에서 오는 것이 중요한 경우 대체됩니다 filter_program <"$output_file"
.)<"$output_file" cat | filter_program
filter_program
기본 프로그램이 실패 시에만 출력을 생성하는 경우 종료 상태를 기다리는 대신 필터가 출력을 생성하는 즉시 시작할 수 있습니다. 이것ifne
유틸리티는 다음에서 비롯됩니다.더 많은 유틸리티이것에 매우 편리합니다.
main_program 2>&1 | ifne filter_program
답변2
를 찾습니까명명된 파이프이와 같이:
## Create a named pipe
$ mkfifo errorPipe
## In another shell session, launch whatever program you want to pipe the
## error to, telling it to read from errorPipe
$ errorCommand < errorPipe
##$ wc -l errorPipe
1 errorPipe 프로그램을 실행하고 stderr를 명명된 파이프 $yourCommand 2> errorPipe로 리디렉션합니다.
이렇게 하면 오류만 표시됩니다 errorCommand
.
$ mkfifo errorPipe
$ wc -l < errorPipe ## this will hang until I write something to errorPipe
이제 다른 터미널을 열고 다음을 실행합니다.
$ perl -le 'sleep(2);
print "this is stdout";
sleep(2);
print STDERR "this is stderr"' 2>errorPipe
this is stdout
2초 후에 this is stdout
현재 터미널에 무엇이 인쇄되어 있는지 볼 수 있습니다. 동시에 wc
다른 터미널에서 시작한 프로세스가 종료되고 결과가 인쇄됩니다.
$ wc -l errorPipe
1 errorPipe