segfaulting 프로그램의 배관 출력


13

ttf2afm때로는 segfaults 및 때로는하지 않는 프로그램 (특히 tetex 3.0의 일부) 을 호출하는 스크립트가 있습니다. 필요한 정보는 segfault 전에 항상 인쇄 되지만 파이프 리디렉션이 실패하지 않고 프로그램이 실패 할 때 파이프에 아무것도 출력하지 않는 데 어려움을 겪고 있습니다.

내가 가진 과정을 parenthesizing, FIFO를 통해 리디렉션을 시도했습니다 true쉘 함수에서 실행하고에 케이스에 넣고, 마지막에 sh -c, 그러나 스크립트는 결코 공정 출력 할 것 같다 아무것도 , 심지어 표준 오류로 재 지정하거나-없습니다.

출력이 가능하다는 것을 알고 있습니다. 명령 줄에서 완벽하게 제공 할 수는 있지만 어떤 이유로 스크립트에서는 제공 할 수 없습니다.

내 질문은, 스크립트가 프로그램 segfaults 사실을 무시하고 어쨌든 출력을 줄 수있는 방법이 있습니까?

BASH 4.1.10 (2) 릴리스를 실행 중입니다.

답변:


12

프로그램은 일반적으로 효율성을 위해 출력을 버퍼링합니다. 즉, 메모리 영역 (버퍼라고 함)에 출력을 누적하고 실제로 버퍼가 가득 찼거나 프로그램의 특정 키 포인트에있을 때만 출력을 얻습니다. 프로그램이 정상적으로 종료되면 출력 버퍼를 플러시합니다 (즉, 남아있는 데이터를 인쇄합니다). 그것이 segfaults 때, 버퍼의 내용이 손실됩니다.

프로그램의 출력이 터미널에 연결될 때 (일반 파일이나 파이프가 아닌) 동작이 다르기 때문에 터미널에서 프로그램을 직접 실행할 때는이 효과가 나타나지 않습니다. 터미널에서 기본 동작은 각 줄의 끝에서 버퍼를 플러시하는 것입니다. 따라서 프로그램이 segfault가 될 때까지 생성 된 모든 완전한 라인을 볼 수 있습니다.

프로그램을 터미널에서 강제로 실행하고 출력을 수집 할 수 있습니다. 가장 간단한 방법은 실행하는 것 script입니다. 해결해야 할 많은 성가심이 있습니다.

  • script 스크립트 파일에 헤더 행을 추가 한 후 나중에 제거해야합니다.
  • script 명령의 상태 코드를 반환하지 않으므로 segfault 또는 기타 오류에 대해 알고 싶다면 어딘가에 저장해야합니다.
  • script정상적인 출력 및 오류가 발생합니다. 오류 출력을 별도의 파일에 저장하는 것이 좋습니다.
export FONT="foo"
script -q -c '
    ttf2afm "$FONT.ttf" 2>"$FONT.ttf2afm-err";
    echo $? >"$FONT.ttf2afm-status"
' "$FONT.ttf2afm-typescript"
tail -n +2 <"$FONT.ttf2afm-typescript" >"foo.afm"
rm "$FONT.ttf2afm-typescript"
if [ "$(cat "$FONT.ttf2afm-status")" -ne 0 ]; then
  echo 1>&2 "Warning: ttf2afm failed"
  cat "$FONT.ttf2afm-err"
fi

출력 버퍼를 0으로 설정하는 쉘 설정과 같은 더 우아한 솔루션이 없습니까?
amphetamachine

4

나는 마침내 시행 착오 과정을 통해 그것을 알아 냈습니다. 솔루션은 복잡합니다.

(trap 'true' ERR; exec ttf2afm "$FONT") |
grep ...

분명히 exec원인 ttf2afm은 트랩 된 오류로 서브 쉘 프로세스를 인계하여 segfaults가 중요하지 않은 환경에서 작동하게합니다.

포괄적 인 ERR신호를 포착하면 서브 쉘이 죽지 않고 프로그램이 실패 할 때 즉시 종료되는 주 스크립트에 신호를 보내는 것이 중지됩니다.

유일한 문제는 커널 자체 가 일단 프로세스 segfault가 발생 하면 전체 스택 추적 가비지 를 콘솔 장치에 직접 출력 하므로, 그것이 아는대로 출력되는 것을 막을 방법이 없지만 중요하지 않습니다. stdout 또는 stderr에는 영향을 미치지 않으므로


3
이것이 당신을 위해 일하는 것이 기쁘지만, bash가 출력 버퍼 크기를 0으로 설정했기 때문에 그것이 작동하는 이유가 아니라고 확신 할 수 있습니다. Bash는 ttf2afm직접 사용되는 버퍼링에 영향을 줄 수 없습니다 . 나는 어떻게 (trap true ERR; exec ttf2afm "$FONT")| …관리가과 다르게 행동 하는지 궁금합니다 ttf2afm "$FONT" | ….
Gilles 'SO- 악한 중지'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.