출력을 다른 프로세스로 파이프하면서 첫 번째 프로세스의 오류 상태를 유지하는 방법은 무엇입니까? [복사]

출력을 다른 프로세스로 파이프하면서 첫 번째 프로세스의 오류 상태를 유지하는 방법은 무엇입니까? [복사]

중복 가능성:
다른 프로세스로 파이프된 종료 코드 가져오기

나는 다음 명령줄(makefile에서)을 사용하여 사람이 읽을 수 있는 내용으로 줄이는 Perl 스크립트를 통해 컴파일러의 자세한 오류 메시지를 전달합니다.

g++ -c source.cpp -o source.o 2>&1 | perl /bin/gSTLFilt.pl

불행하게도 이 접근 방식은 명령에서 반환된 오류 값을 "마스크"합니다 g++. make는 명령의 오류 결과 g++만 반환하므로 명령이 실패했다는 사실을 알지 못합니다 .perl

출력을 파이프하고 원래 오류 조건을 계속 유지하는 방법이 있습니까?

차이가 나는 경우: 저는 GNU bash 버전 2.04.0(1)-릴리스(i686-pc-)를 실행하는 MSYS 콘솔에서 GNU Make 3.81 및 g++(GCC) 3.4.5(mingw-vistaspecial r3)를 사용하고 있습니다. msys)(Windows XP).

답변1

sh.exeWindows 실행 파일에 해당 이름을 사용하는 여러 셸이 있기 때문에 셸이 무엇을 제공하는지 잘 모르겠지만 , bash비슷하거나 유사하다면 배열을 사용할 수 있습니다 $PIPESTATUS. 귀하의 예를 들어 다음과 같이 할 수 있습니다:

g++ -c source.cpp -o source.o 2>&1 | perl /bin/gSTLFilt.pl
echo "${PIPESTATUS[0]}"

답변2

Bash에는 다음과 같은 옵션이 있습니다 pipefail.

The return status of a pipeline is the exit status of the last command,
unless  the  pipefail  option  is enabled.  If pipefail is enabled, the
pipeline's return status is the value of the last  (rightmost)  command
to  exit  with a non-zero status, or zero if all commands exit success-
fully.

그래서:

set -o pipefail && $GCC_COMMAND | $PERL_COMMAND

Make는 각 라인에 대해 서브쉘의 각 라인을 실행합니다.이므로 gcc 줄의 시작 부분에 추가해야 합니다. set을 사용하여 make가 하나의 명령만 실행하도록 하는 방법이 있을 수 있지만 pipefail잘 모르겠습니다.

(SHELL=/bin/bash제작자는 이것을 사용해야합니다)

아니면 다음을 시도해 보세요.

bash -o pipefail -c "$GCC_COMMAND | $PERL_COMMAND"

답변3

기존 셸에서는 파이프라인의 첫 번째 명령 상태가 스크립트에 전혀 보고되지 않습니다. 에서는 마지막 명령의 상태만 사용할 수 있습니다 $?.

배쉬 ≥3.0에서는,파이프라인 어디에서나 오류가 발생하면 중지하고 싶을 때 이 pipefail옵션을 사용하세요..

g++ -c source.cpp -o source.o 2>&1 | perl /bin/gSTLFilt.pl

보다 일반적으로 Bash에서는 PIPESTATUS배열이 $?마지막 파이프라인의 모든 명령을 포함하도록 일반화됩니다.

$ (exit 1) | (exit 2) | (exit 3); echo ${PIPESTATUS[@]}
1 2 3

Zsh에도 동일한 기능이 있지만 배열을 호출합니다 pipestatus.

% zsh -c '(exit 1) | (exit 2) | (exit 3); echo $pipestatus'    
1 2 3

bash(IIRC는 msys에서 제공하는 쉘)를 사용하려는 경우 sh이를 사용할 수 있습니다 PIPESTATUS. 그렇지 않은 경우 종료 상태를 최상위 쉘로 파이프하고 필터 프로그램을 종료하도록 할 수 있습니다. 입력의 마지막 줄을 읽어 일반 입력으로 사용하는 대신 종료할 상태를 가져옵니다. 투박하지만 유용합니다.

메이크파일에서는 컴파일러 메시지가 또 다른 중간 파일로 처리되는 임시 파일을 사용하는 것이 비교적 일반적입니다.

%.otmp %.g++-log: %.cpp
        g++ -c $< -o $@tmp 2>&1 >$*.g++-log
%.o: %.otmp %.g++-log
        perl /bin/gSTLFilt.pl <$*.g++-log
        mv $*.otmp $@

관련 정보