bash set -o errexit가 문제입니까, 아니면 변수를 증가시키는 방식입니까?

bash set -o errexit가 문제입니까, 아니면 변수를 증가시키는 방식입니까?

다음 예와 같이 set -e를 사용하여 변수를 증가시키는 쉘 스크립트가 있습니다.

$ var=0; echo $?
0
$ ((var++)); echo $?
1
$ ((var++)); echo $?
0
$ ((var++)); echo $?
0
$ echo $var; echo $?
3
0
$ bash --version
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later  <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.    
$

스크립트가 예기치 않게 종료되었습니다. 문제는 똑같은 스크립트입니다아니요MacBook에서 로컬로 실행할 때도 같은 방식으로 종료합니다. MacBook의 bash 쉘은 위 예제를 실행할 때와 정확히 동일한 방식으로 작동합니다.

여기서 무슨 일이 일어나고 있는지 아는 사람 있나요?

답변1

산술 표현식의 값이 0이 아니면 산술 명령이 성공합니다. 표현식이 0으로 평가되면 명령은 상태 1로 실패합니다. 쉘 산술 표현식의 부울 연산자가 참이면 0을, 거짓이면 1을 반환하기 때문에(C에서처럼) 산술 명령을 테스트에 사용할 수 있습니다. 예를 들어

if ((x==3)); then …

((x==3))이는 3과 같을 때 0을 반환하고 그렇지 않으면 1을 반환하기 때문에 작동합니다 .$x

후위 증가 연산자는 변수의 이전 값을 반환합니다. 따라서 이전에 0이었던 경우 ((var++))오류 상태가 반환됩니다.var

set -e첫 번째 명령이 실패하면 쉘이 종료되도록 지시합니다. 거기에는 놀라운 일이 없습니다.

합법적으로 값이 0일 수 있는 산술 표현식으로 인해 발생하는 불필요한 오류를 방지하려면 산술 명령을 사용하지 말고 대신 산술 표현식에 일반 할당을 사용하십시오.

var=$((var+1))

답변2

예를 들어 항상 산술 명령을 사용할 수 있습니다 ((var++)). 할당 전에 var의 값이 0인 경우 성공 상태 코드를 강제로 작성하면 됩니다.((var++)) || true

또는 다음을 작성하여 오류 종료 논리를 건너뛸 수 있습니다.! ((var++))

답변3

을 사용하는데 declare -i i=0; i+=1종료 코드는 0입니다.

전에 해킹을 썼어요i=0; ((i++)) ||true

관련 정보