Bash에서 매우 구체적인 오류 메시지를 무시하십시오.

Bash에서 매우 구체적인 오류 메시지를 무시하십시오.

script.sh:

#!/bin/bash
my-bin-file-i-run

if [ $? -eq 0 ]
then
    exit 0
else
    if [[ >&2 == *"name_to_handle_at"* ]]; then
        exit 0
    fi
    echo >&2
    exit 1
fi

명령을 실행하고 싶은데 메시지에 "name_to_handle_at" 오류가 발생하면 스크립트에 오류가 없는 것처럼 처리하고 다른 모든 오류는 평소대로 표시됩니다. 실제로 작동시킬 수 없습니다.

답변1

==이전에 실행된 명령의 표준 오류를 유사한 명령 과 비교할 수 없기 때문에 구문에 문제가 있습니다 .

한 가지 제안은 오류 스트림을 파일에 저장한 다음 파일을 구문 분석하는 것입니다.

#!/bin/bash

if ! my-bin-file-i-run 2>error.log; then
    if ! grep -q -F 'name_to_handle_at' error.log; then
       echo 'some error message' >&2
       exit 1
    fi
fi

그러면 명령이 실행되고 표준 오류 스트림이 이라는 디렉터리로 리디렉션됩니다 . error.log명령이 오류로 종료된 경우 로그 파일에서 문자열을 찾는 grep데 사용됩니다 . name_to_handle_at찾지 못하면 오류 메시지가 인쇄되고 스크립트는 0이 아닌 종료 상태로 종료됩니다.

다른 경우에는 스크립트가 종료 상태 0으로 종료됩니다.

error.log스크립트가 종료될 때 파일을 삭제 하려면 명시적으로 rm error.log해당 위치에서 또는 트랩을 사용하여 EXIT삭제할 수 있습니다.

#!/bin/bash

trap 'rm -f error.log' EXIT

if ! my-bin-file-i-run 2>error.log; then
    if ! grep -q -F 'name_to_handle_at' error.log; then
       echo 'some error message' >&2
       exit 1
    fi
fi

답변2

프로그램의 stderr을 grep으로 파이프하여 사용할 수 있습니다(배쉬 특정) PIPESTATUS명령 성공/실패 및 명령 인쇄/오류 메시지 인쇄 안 함의 4가지 조합을 구별하는 변수:

{ your_command 2>&1 >&3 | grep your_error_message >/dev/null; } 3>&1
case ${PIPESTATUS[*]} in
0*) ;; # the command succeeded
*0) ;; # the command failed but printed the error message
esac

예:

# usage wrapper pattern cmd args ...
wrapper(){
    msg=$1; shift
    { "$@" 2>&1 >&3 | grep "$msg" >/dev/null; } 3>&1
    case ${PIPESTATUS[*]} in
    0*|*0) return 0;;
    *) return "${PIPESTATUS[0]}";;
    esac
}

# usage test_cmd status error_message
test_cmd(){ status=$1; shift; echo >&2 "$@"; return "$status"; }

$ wrapper foo test_cmd 13 foo; echo $?
0
$ wrapper foo test_cmd 13 bar; echo $?
13

노트:

grep >/dev/null로 바꾸지 마십시오 grep -q. 그러면 첫 번째 일치에서 grep이 종료되고 명령이 SIGPIPE로 표시됩니다.

그러나 ... | tee /dev/stderr | ...명령과 grep 사이에 하나를 추가하면 오류 메시지가 grep에 전달되고 stderr에 인쇄됩니다.

많은 저수준 프로그램(특히 Python 스크립트)은 stderr 대신 stdout에 오류 메시지를 기록합니다.

your_command 2>&1 | ...

{ 2>&1 >&3 | ... } >&3그 fd 저글링 대신 .

관련 정보