Shell関数のローカル変数の範囲

Shell関数のローカル変数の範囲

読んだ後24.2。ローカル変数var、キーワードを使用して変数を宣言することは、関数の中かっこで区切られたコードブロック内でのみその値にアクセスできることlocalを意味すると思いました。var

varしかし、次の例を実行した後、このコードブロックで呼び出された関数からアクセス、読み書きすることができることがわかりました。つまり、 とvar宣言された場合でも依然として読み取り変更することができます。値。localouterFuncinnerFunc

Run It Online

#!/usr/bin/env bash

function innerFunc() {
    var='new value'
    echo "innerFunc:                   [var:${var}]"
}

function outerFunc() {
    local var='initial value'

    echo "outerFunc: before innerFunc: [var:${var}]"
    innerFunc
    echo "outerFunc: after  innerFunc: [var:${var}]"
}

echo "global:    before outerFunc: [var:${var}]"
outerFunc
echo "global:    after  outerFunc: [var:${var}]"

出力:

global:    before outerFunc: [var:]               # as expected, `var` is not accessible outside of `outerFunc`
outerFunc: before innerFunc: [var:initial value]
innerFunc:                   [var:new value]      # `innerFunc` has access to `var` ??
outerFunc: after  innerFunc: [var:new value]      # the modification of `var` by `innerFunc` is visible to `outerFunc` ??
global:    after  outerFunc: [var:]

Q:これは私のシェル(bash 4.3.42、Ubuntu 16.04、64ビット)のバグですか、それとも予想される動作ですか?

編集する:解決しました。 @MarkPlotnickが指摘したように、これは実際に予想される動作です。

ベストアンサー1

シェル変数にダイナミックレンジ。変数が関数に対してローカルに宣言されている場合、その範囲は関数が返されるまで有効です。他の関数の呼び出し中に含める

これはほとんどのプログラミング言語とは明らかに対照的です。語彙範囲。 Perl には次の両方があります。my語彙範囲の場合、localまたは動的範囲のない宣言です。

2つの例外があります。

  1. ksh93 で標準構文を使用して関数を定義すると、function_name () { … }そのローカル変数は動的スコープに従います。ただし、関数がksh構文を使用して定義されている場合、function function_name { … }そのローカル変数は語彙/静的範囲に従うため、呼び出された他の関数には表示されません。

  2. zsh/private自動ロードプラグインは、静的範囲で変数を宣言するために使用できるキーワード/組み込み関数を提供zshしますprivate

ash、bash、pdksh、およびその派生物であるboshにはダイナミックレンジしかありません。

おすすめ記事