출력의 마지막 줄 또는 종료 코드를 얻는 방법

출력의 마지막 줄 또는 종료 코드를 얻는 방법

저는 Bash에서 자동 숙제 채점기를 작성하고 있습니다. 그레이더는 프로그램을 컴파일하고 실행합니다. 프로그램이 컴파일 또는 실행에 실패하는 경우(예: 분할 오류로 인해) 등급은 5와 같이 고정된 작은 숫자여야 합니다. 그렇지 않으면 레벨은 프로그램 출력의 마지막 라인입니다.

마지막 행을 얻으려면 다음을 수행할 수 있습니다.

grade=$( ./a.out | tail -1 )

그러나 이는 a.out을 실행할 수 없는 경우(예: 찾을 수 없는 경우)에도 항상 종료 코드 0을 제공하므로 프로그램이 존재할 수 없는지 알 수 없습니다.

또 다른 옵션은 임시 파일을 사용하는 것입니다.

./a.out > temp
if [ $? -ne 0 ]
then
  grade=0
else
  grade=$( tail -1 temp )
fi

그러나 동시에 동일한 작업을 수행하는 여러 프로세스가 있는 경우 문제가 발생할 수 있습니다. 하나의 프로세스를 사용하더라도 마지막 줄만 필요할 때 모든 출력을 하나의 파일에 보관하는 것은 낭비입니다(출력이 상당히 클 수 있음).

임시 파일을 사용하지 않고 해결 방법이 있나요?

답변1

grade=$( { ./a.out 2>/dev/null || echo 0; } | tail -n 1 )

프로그램이 0이 아닌 종료 상태로 종료되거나 전혀 실행에 실패하면 실행을 시도한 ./a.out다음 출력에 한 줄을 추가합니다. 잡혀서 에 배치 0됩니다 .0tail -n 1$grade

올바르게 실행 되고 ./a.out0 종료 상태로 종료되면 echo트리거되지 않습니다.

/dev/null실행 관련 진단 메시지를 보려면 표준 오류 리디렉션을 제거하세요 ./a.out.

종료 코드를 얻으려면 0로 변경하세요 . "$?"숫자와 오류를 구별하려면 NaN일부 오류 문자열을 사용해야 할 수도 있습니다.

답변2

귀하의 질문은 "임시 파일을 사용하지 않고 출력의 마지막 줄을 얻고 비정상적인 종료를 감지하고 싶습니다"로 요약됩니다. 이 경우, set -o pipefail그 사람은 당신의 친구입니다.

다음은 인수를 실행하고 정상적으로 종료할 때 출력의 마지막 줄을 기록하는 간단한 스크립트입니다.

#!/bin/bash

[[ -x $1 ]] || {
    echo >&2 "Usage ${0##*/} <PROGRAM> [ARG1] ..."
    exit 1
}

set -o pipefail
program=$1
shift;
x=$($program "$@" | tail -1)

if [[ $? -eq 0 ]]; then
    echo "Pass: $x"
else
    echo "Fail: $?"
fi

등급 문제는 여러분에게 맡기겠습니다.

관련 정보