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  []

関連情報