グローバルおよびローカル変数の割り当て

グローバルおよびローカル変数の割り当て

私はいくつかのオンラインチュートリアルを通してシェルスクリプトを学んでおり、グローバル変数とローカル変数の違いを宣言する次のスクリプトを得ました。

#!/bin/bash
# Experimenting with variable scope
var_change () {
  local var1='local 1'
  echo Inside function: var1 is $var1 : var2 is $var2
  var1='changed again'
  var2='changed again'
}

var1='global 1'
var2='global 2'

echo Before function call: var1 is $var1 : var2 is $var2

var_change

echo After function call: var1 is $var1 : var2 is $var2

出力は次のとおりです

関数呼び出し前:var1はグローバル1:var2はグローバル2

内部機能: var1ローカル1:var2はグローバル2

関数呼び出し後:var1はグローバル1:var2は再変更

私の質問...

var1関数呼び出し後に「再変更」の代わりに「グローバル1」があるのはなぜですか?誰かがこれを説明できますか?

答え1

var1関数内でローカルに宣言されました。したがって、関数の実行中に次のようなものがあります。二つ変数名var1:グローバル変数とローカル変数。ただし、関数はローカル関数のみを「見る」ことができます(ローカル関数はグローバル関数を「隠します」)。したがって、関数内で実行するすべての操作はローカルvar1変数に対して実行され、グローバル変数はvar1まったく触れません。

答え2

これについて考える1つの方法は、現在の値を保存し、関数の終わりにそれを復元してから設定することを約束するlocal var1="local 1"効果を想像することです。この精神モデルを使用すると、すべての変数をグローバル変数として処理し、関数の末尾から変数を復元できます。var1"local 1"

varこの例は、関数の内側と外側の両方でechoを呼び出すのではなく、別の出力関数を呼び出す方が良いでしょう。

bash$ show(){ printf "   The value of %s in %s is '%s'\n" $1 $2 ${!1} ; }
bash$ bar(){ show v1 bar_$1 ; }
bash$ foo(){ show v1 before_foo ; local v1 ; show v1 after_local ; \ 
               v1="changed"; show v1 after_change ; bar via_foo ; }
bash$ v1="global"
bash$ show v1 global_scope
   The value of v1 in global_scope is 'global'
bash$ foo
   The value of v1 in before_foo is 'global'
   The value of v1 in after_local is ''
   The value of v1 in after_change is 'changed'
   The value of v1 in bar_via_foo is 'changed'
bash$ bar direct
   The value of v1 in bar_direct is 'global'
bash$ show v1 global_scope
   The value of v1 in global_scope is 'global'

ここで、fooによって設定されたv1の値は、foo内のbar呼び出しから得られることがわかります。

Web検索がdynamic scope役に立つlexical scopeかもしれません。

答え3

Bashはローカル変数を明示的に呼び出す必要があり、そうでない場合はグローバル変数として扱われます。範囲が適用される関数の内部でも可能です。

そして、変数に最終的に設定された範囲(ローカル、単語の明示的な宣言によるローカル、またはlocal省略によるグローバル)は、viaが呼び出されたときに返されますecho

したがって、あなたの例では、関数が呼び出された後にローカルスコープがに設定され、var1この変数に対するすべての変更は関数の外に残りません。ただし、グローバルはに設定されているため、var2この変数は変更されます。

関連情報