Bash의 변수 정의 변경

Bash의 변수 정의 변경

definedBash 3.00.16에서는 Bash 4.2.24에서 다음을 인쇄합니다 undefined.

my_test() {
    local foo
    if [ -n "${foo+defined}" ]
    then
        echo defined
    else
        echo undefined
    fi
}
my_test

분명히 관련된 내용을 찾을 수 없습니다.배쉬 변경페이지.

  • 언제 이렇게 바뀌었나요?
  • 이는 버그 수정으로 간주됩니까, 아니면 다른 변경 사항의 부작용으로 간주됩니까? 즉, 현재의 행동이 안정적인 것으로 간주될 수 있습니까?

답변1

Bash 4.0부터 이 동작이 변경되었으며 가변 범위 버그 수정인 것으로 보입니다. 동일한 이름의 전역 변수가 있는지에 따라 코드 동작이 변경됩니다.

4.0 이전 버전에서는

  • variable로컬과 동일한 이름으로 전역을 정의하면 ${variable+override}레코드별로 작동합니다.
  • 전역 변수가 없으면 ${variable+override}대체 값이 사용됩니다.

이는 전역 범위 문제에서 일반적으로 기대하는 것과 반대입니다. local이전 버전의 Bash에서 변수가 다르게 설정되거나 +변수가 다르게 조회되는 데는 전역적인 이유가 있을 수 있습니다 .

@rush 가 언급 했듯이 ${foo:+defined}. 이를 설명하는 @choroba 및 @chepner가 추가되었습니다.${1+"$@"}man bash콜론을 생략하면 설정되지 않은 매개변수만 테스트됩니다..

다음 수정된 함수를 사용하십시오(함수 이름을 변수와 동일하게 지정하는 것은 아무 영향도 미치지 않지만 오류를 유발할 수 있다고 생각되는 첫 번째 것입니다).

foo() {
    echo "global bar [${bar+defined}]"
    local bar
    echo "local bar  [${bar+defined}]"
}

4.0.0(1)-출시됨

$ echo $BASH_VERSION
4.0.0(1)-release
$ unset bar
$ foo
global bar []
local bar  []
$ bar=test
$ foo
global bar [defined]
local bar  []

3.2.0(1)-릴리스

$ echo $BASH_VERSION
3.2.0(1)-release
$ unset bar
$ foo
global bar []
local bar  [defined]
$ bar=test
$ foo
global bar [defined]
local bar  []

3.00.16(1) - 출시됨

$ echo $BASH_VERSION
3.00.16(1)-release
$ unset bar
$ foo
global bar []
local bar  [defined]
$ bar=test
$ foo
global bar [defined]
local bar  []

2.05b.0(1)-출시됨

$ echo $BASH_VERSION
2.05b.0(1)-release
$ unset bar
$ foo
global bar []
local bar  [defined]
$ bar=test
$ foo
global bar [defined]
local bar  []

관련 정보