안전 측면에서 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!
$
우리는 $?
구문 오류를 잡기 위해 모든 명령문을 검사 할 수 없습니다 .
(나는 합리적인 프로그래밍 언어에서 그러한 안전한 행동을 기대했다. 아마도 이것은 개발자를 강타하는 버그 / 소위로보고되어야한다)
더 많은 실험
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!
$
아마도 이것은 http://mywiki.wooledge.org/BashFAQ/105의 연습 2와 관련이 있으며 관련 이 있습니다 (( ))
. 그러나 구문 오류가 계속 발생하면 여전히 불합리합니다.
아니요, (( ))
차이가 없습니다!
산술 테스트 없이도 잘못 작동합니다! 간단하고 기본적인 스크립트 :
#!/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!
$
답변
전체를 함수로 감싸는 것은 트릭을 수행하는 것처럼 보입니다.
#!/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 "#")
$
왜 실마리는 없지만 다른 누군가가 설명 할 수 있습니까?
답변
의 진정한 의미에 대해 오도했을 것입니다 set -e
. help set
쇼 의 출력을주의 깊게 읽습니다 .
-e Exit immediately if a command exits with a non-zero status.
그래서 -e
의 종료 상태에 관한 명령이 아닌 스크립트 구문 오류에 대한 비 – 제로, 인.
일반적으로 set -e
모든 오류 (예 : 명령에서 0이 아닌 모든 반환 값)는 스크립트에서 스마트하게 처리해야하므로 강력한 스크립트를 생각해야합니다. 공간 또는 하이픈으로 시작).
구문 오류 유형에 따라 스크립트가 전혀 실행되지 않을 수도 있습니다. 나는 bash에서 어떤 클래스의 구문 오류 (만 분류 할 수있는 경우)가 스크립트를 즉시 중단시킬 수 있는지 정확하게 알 수 없습니다. 어쩌면 일부 배쉬 전문가들이 참여하여 모든 것을 명확히 할 것입니다.
나는 그 set -e
진술을 명확히하기를 희망한다 !
당신의 소원에 관하여 :
나는 현명한 프로그래밍 언어로부터 그러한 안전한 행동을 기대했다.
대답은 확실히 아니오입니다! set -e
실제로 관찰 한 내용 ( 예상대로 응답하지 않음)이 실제로 잘 기록되어 있습니다.
답변
다음과 같은 것을 넣어 스크립트 자체를 확인할 수 있습니다.
bash -n "$0"
스크립트의 맨 위 근처- set -e
중요한 코드의 앞뒤 .
나는 이것이 매우 강하게 느껴지지 않는다고 말해야하지만 그것이 당신에게 효과적이라면 아마도 받아 들일 수 있습니다.
답변
먼저 (( ))
in bash는 산술 계산으로 사용되며 if …에는 사용하지 않습니다 []
.
둘째, ${a[#]}
이상하고 그것이 오류를 일으키는 이유입니다 … #
배열 의미가 없습니다.
난 당신이 수행 할 작업 모르겠지만, 당신이 원하는 그래서, 당신은 필드의 수를 알고 싶은 가정 ${#a[*]}
대신
마지막으로 정수를 비교할 때 (문자열에 사용) -eq
이상을 권장 ==
합니다. 는 ==
또한 작동하지만 -eq
권장합니다.
그래서 당신은 원합니다 :
if [ ${#a[*]} -eq 2 ]; then