충돌하는 프로그램의 표준 출력과 셸의 "segfault" 메시지를 캡처합니다.

충돌하는 프로그램의 표준 출력과 셸의 "segfault" 메시지를 캡처합니다.

main.bin인쇄해야 하는 컴파일된 프로그램이 있습니다 .

hello world
another line

프로그램은 첫 번째 줄을 인쇄한 직후 분할 오류를 생성합니다.

쉘(zsh)에서 실행하면 다음과 같은 결과가 나타납니다.

Hello world
[1]    3503 segmentation fault (core dumped)  ./main.bin

그러나 stdout의 일부를 리디렉션하여 사용하려고 하면 아무것도 없습니다. 이는 표준 출력 버퍼가 누락되었기 때문입니다. 따라서 이 unbuffer도구를 사용하면 작동하게 할 수 있습니다.

$ unbuffer ./main.bin > tee out.log
Hello world
$ cat out.log
Hello world

좋아요 이제 셸에서 제공하는 분할 오류 메시지도 캡처하고 싶습니다.

$ (sh -c ./main.bin) 2> err.log
Hello world
$ cat err.log
Segmentation fault (core dumped)

좋아요, 둘 다 따로 구할 수 있어요. 그런데 같이 캡쳐하려고 하면 main.bin을 두 번 호출하는 것 외에는 방법을 찾을 수가 없습니다. 서브셸 내에서만 버퍼 해제를 사용하면 분할 오류가 발생하지 않습니다. 그리고 프로그램을 호출하는 것만으로는 출력이 인쇄되지 않습니다.


내 목표는 프로그램의 (아마도 부분) 출력을 stdout으로 인쇄하고, 버그가 있는 프로그램으로 인해 쉘이 생성할 수 있는 분할 오류, 스택 오버플로 등을 stderr로 인쇄하는 스크립트를 만드는 것입니다.

내 현재 솔루션(더 이상 답변을 게시하지 않음)은 다음을 포함하는 스크립트입니다.

subject="$1"
out=$(unbuffer "$subject")
err=$(sh -c "$subject" 2>&1 1>/dev/null)
echo ">o> $out"
>&2 echo ">e> $err"

스크립트에서 main.bin을 두 번 호출하고 각 std{out,err}를 에코하는 것 외에 이를 달성하는 더 우아한 방법이 있습니까? 나는 여기에서 다른 유사한 항목을 읽었습니다.[1] [2] [삼], 그러나 번거롭거나 내 문제에 직접 매핑되지 않습니다.

답변1

리디렉션을 위해 &>!

echo foo &> /dev/null

확인하다https://tldp.org/LDP/abs/html/io-redirection.html, 또한.

답변2

한 가지 가능한 대답은 두 가지 다른 스크립트를 사용하는 것입니다.

  • subrun.sh: 여기에서는 stderr을 파일로 추출합니다.
./main.bin 2>err.log;
  • run.sh: 여기서는 버퍼링되지 않은 표준 출력을 수집하고 각 출력을 해당 위치에 인쇄합니다. 또한 main.bin에서 제공한 반환 코드를 반환합니다.
echo "">out.log>err.log
unbuffer ./subrun.sh > out.log
ret_code="$?"
cat out.log #cat to stdout
cat err.log >&2 # cat to stderr
return $ret_code # return program's return code

관련 정보