bash가 구문 오류로 인해 스크립트 실행을 중단하도록 만드는 방법은 무엇입니까?

bash가 구문 오류로 인해 스크립트 실행을 중단하도록 만드는 방법은 무엇입니까?

안전을 위해 구문 오류가 발생하면 bash가 스크립트 실행을 중단하도록 하고 싶습니다.

놀랍게도 나는 이것을 달성할 수 없었다. (set -e부족한. ) 예:

#!/bin/bash

# Do exit on any error:
set -e

readonly a=(1 2)

# A syntax error is here:

if (( "${a[#]}" == 2 )); then
    echo ok
else
    echo not ok
fi

echo status $?

echo 'Bad: has not aborted execution on syntax error!'

결과(bash-3.2.39 또는 bash-3.2.51):

$ ./sh-on-syntax-err
./sh-on-syntax-err: line 10: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$ 

$?글쎄, 구문 오류를 찾기 위해 모든 명령문을 확인할 수는 없습니다 .

(나는 합리적인 프로그래밍 언어에서 이러한 안전한 동작을 기대합니다... 아마도 이것은 bash 개발자에게 버그/요망으로 보고되어야 할 것입니다)

더 많은 실험

if다른 점이 없다.

삭제 if:

#!/bin/bash

set -e # exit on any error
readonly a=(1 2)
# A syntax error is here:
(( "${a[#]}" == 2 ))
echo status $?
echo 'Bad: has not aborted execution on syntax error!'

결과:

$ ./sh-on-syntax-err 
./sh-on-syntax-err: line 6: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$ 

아마도 운동 2와 관련이 있을 것 같습니다.http://mywiki.wooledge.org/BashFAQ/105와 연관되다 (( )). 하지만 구문 오류를 발견한 후에도 계속 실행하는 것은 여전히 ​​의미가 없습니다.

아니요, (( ))차이가 없습니다!

산술 테스트 없이도 성능이 좋지 않았습니다! 간단한 기본 스크립트:

#!/bin/bash

set -e # exit on any error
readonly a=(1 2)
# A syntax error is here:
echo "${a[#]}"
echo status $?
echo 'Bad: has not aborted execution on syntax error!'

결과:

$ ./sh-on-syntax-err 
./sh-on-syntax-err: line 6: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$ 

답변1

모든 것을 함수로 감싸는 것이 트릭을 수행하는 것 같습니다.

#!/bin/bash -e

main () {
readonly a=(1 2)
    # A syntax error is here:
    if (( "${a[#]}" == 2 )); then
        echo ok
    else
        echo not ok
    fi
    echo status $?
    echo 'Bad: has not aborted execution on syntax error!'
}

main "$@"

결과:

$ ./sh-on-syntax-err 
$ ./sh-on-syntax-err line 6: #: syntax error: operand expected (error token is "#")
$ 

이유는 모르겠지만 다른 사람이 설명할 수 있을까요?

답변2

당신은 그 진정한 의미를 오해했을 수도 있습니다 set -e. help set표시된 출력을 주의 깊게 읽으십시오 .

-e  Exit immediately if a command exits with a non-zero status.

-e종료 상태도 마찬가지입니다.주문하다스크립트의 구문 오류와 관계없이 0이 아닙니다.

set -e일반적으로 )를 사용합니다

구문 오류 유형에 따라 스크립트가 전혀 실행되지 않을 수도 있습니다. 나는 bash에 대해 말할 만큼 지식이 없다정확히어떤 유형의 구문 오류가 분류될 수 있는지에 따라 스크립트가 즉시 종료될 수 있습니다. 어쩌면 일부 Bash 전문가가 개입하여 모든 것을 명확히 할 수도 있습니다.

이 진술을 명확히 했으면 좋겠습니다 set -e!

귀하의 희망사항에 관하여:

나는 합리적인 프로그래밍 언어에서 이러한 안전한 동작을 기대합니다... 아마도 이것은 bash 개발자에게 버그/희망으로 보고되어야 할 것입니다.

대답은 '예'입니다아니요!관찰한 대로( set -e예상대로 응답하지 않음) 실제로 꽤 잘 문서화되어 있습니다.

답변3

다음과 같은 것을 입력하여 스크립트 자체를 확인하도록 할 수 있습니다.

bash -n "$0"

스크립트 상단 근처 - set -e중요한 코드 앞과 뒤.

나는 이것이 매우 강력하다고 느끼지는 않지만 그것이 당신에게 효과가 있다면 아마도 받아들일 수 있을 것이라고 말하고 싶습니다.

관련 정보