いくつかのオンラインチュートリアルを通じてシェルスクリプトを学習していて、次のスクリプトにたどり着きました。これは、グローバル変数とローカル変数の違いを宣言します。
#!/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 "の関数呼び出しが再度変更されました"?誰かが説明できますか?
回答
var1
は関数でローカルとして宣言されています。したがって、関数の実行中に、var1
という名前の 2つの変数があります。グローバル変数とローカル変数です。ただし、関数はローカルのもののみを「見る」ことができます(ローカルのものはグローバルなものを「シャドウ」します)。したがって、関数内では、var1
に対して行うことはすべてローカル変数に対して行われます。グローバルなvar1
にはまったく触れられていません。
回答
への1つの方法local var1="local 1"
がvar1
の現在の値を保存する効果があり、最後に復元される関数を"local 1"
に設定します。このメンタルモデルを使用すると、すべての変数をグローバルと見なすことができ、変数は関数の最後に復元されます。
関数の内部と外部の両方でechoを呼び出すのではなく、 var
を出力した別の関数を呼び出しました。
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の内部からbarを呼び出すと、fooによって確立されたv1の値が取得されます。
dynamic scope
とlexical scope
のウェブ検索が役立つ場合があります。
コメント
- "関数の最後に復元されます"、これで私の心がはっきりします!ありがとう
回答
Bashでは、ローカル変数を明示的に呼び出す必要があります。そうしないと、グローバル変数として扱われます。 。関数の内部(スコープが適用される場所)でも。
そして、変数に最後に設定されたスコープはすべて、ローカルで、単語local
、または省略によるグローバル-echo
を介して呼び出されたときに返されるものになります。
つまり、たとえば、関数が呼び出された後、ローカルスコープはvar1
に設定されるため、この変数への変更は関数の外部では保持されません。ただし、グローバルはvar2
に設定されたままなので、この変数を変更すると