논리식에서 처리되지 않은 런타임 오류에 대해 Bash에서 방어적으로 코딩하는 방법은 무엇입니까?

논리식에서 처리되지 않은 런타임 오류에 대해 Bash에서 방어적으로 코딩하는 방법은 무엇입니까?

방금 오류가 발생했습니다. 스크립트에 함수가 없습니다. 스크립트를 조기에 중지하기 위해 이러한 예외를 발생 시켰지만 trap이런 일이 발생하지 않는 것을 확인했습니다. 이를 더 자세히 살펴보면, 논리식의 일부로 발생하는 오류는 오류 자체가 아닌 해당 식의 일부로 간주된다는 사실을 발견했습니다.

예를 들어 다음 코드 조각을 참조하세요.

function _raise_error() {
    >&2 echo "Error on line $1"
}

trap '_raise_error $LINENO' ERR

# STDERR: _missing_function: command not found
_missing_function && echo "This expression is never true"

echo "This is printed, because the missing function error is not trapped"

논리 표현식에서 함수가 누락된 경우 스크립트가 일찍 종료되도록 이 코드를 보다 방어적으로 작성하는 더 좋은 방법이 있습니까? 이걸 어떻게 캡처해야 할지 모르겠습니다. 이 경우에는 set -e이미 오류를 포착하고 스크립트를 종료했으므로 아무런 차이가 없습니다.

내 최선의 추측은 내가 줄을 감쌀 필요가 있다는 것입니다 false. 이상적인 것은 아니지만 더 좋은 방법이 생각나지 않습니다.

_missing_function && { echo "This expression is never true"; } || false

답변1

이 특정 오류의 경우 다음을 수행할 수 있습니다.

$ cat tst.sh
#!/usr/bin/env bash

_raise_error() {
    echo "Error on line $1" >&2
}

command_not_found_handle() {
    _raise_error "${BASH_LINENO[0]}"
    kill -SIGUSR1 "$$"
}

trap '_raise_error "$LINENO"' ERR
trap 'exit 127' SIGUSR1

_missing_function && echo "This expression is never true"

echo "This is printed, because the missing function error is not trapped"

$ ./tst.sh
Error on line 15

또는 _raise_error()트랩에서 호출하고 다음을 수행하도록 하려면 exit:

$ cat tst.sh
#!/usr/bin/env bash

_raise_error() {
    echo "Error on line $1" >&2
    exit "$2"
}

command_not_found_handle() {
    echo "${BASH_LINENO[0]}" > "$tmpCnf"
    kill -SIGUSR1 "$$"
    return 127
}

tmpCnfh=$(mktemp) || exit
trap 'rm -f "$tmpCnfh"; exit' EXIT
trap '_raise_error "$LINENO" "$?"' ERR
trap 'es="$?"; _raise_error "$(<"$tmpCnfh")" "$es"' SIGUSR1

_missing_function && echo "This expression is never true"

echo "This is printed, because the missing function error is not trapped"

$ ./tst.sh
Error on line 19

자세한 내용은 다음을 참조하세요.

관련 정보