変数はいつローカルで、いつグローバルですか?

変数はいつローカルで、いつグローバルですか?

次の2つの機能を考えてみましょう。

f1() {
  if [ "$a" == "" ]; then
    a="0";
  else
    a=$(($a+1));
  fi;
  echo "$a";
}

f2() {
  echo "f1(): $($1)";
}

f1何度も呼び出すと期待aどおりに増加します。

$ f1
0
$ f1
1
$ f1
2

しかし、私が遺跡f1からf2 a呼んだ場合0

$ f2 "f1"
f1(): 0
$ f2 "f1"
f1(): 0

関数で宣言された変数がグローバル変数であることを聞いて経験しました。それでは、なぜそのような違いがありますか?これは特別なケースですか、それとも私が正しい方法でf1呼び出さないのですか?f2

f2さて、私は定義が次のように変更されたことを確認しました。

f2() {
  eval "$1";
}

問題は解決しましたが、最初の呼び出しの目的が何であるかを知ることはまだ面白いです$($1)。正確にどんな役割を果たしますか?

また。f1f2

f2() {
  ...
  res=$(eval "$1");
  ...
}

res通話するたびに同じです。f2 "f1"

なぜ?

答え1

f1で次のように定義されている場合、値はaグローバルですa

local a

f1 定義を次に変更します。

f1() {
       local a
       if [ "$a" == "" ]; then
           a="0";
       else
           a=$(($a+1));
       fi;
           echo "$a";
     }

変数をローカルにします。

f2の場合:サブシェル$(f2)からf2を呼び出します。子シェル変数は親シェルには影響しません。

答え2

subshel​​lに言及しているすべてのコメントに感謝します。しかし、もう少し詳しく答えたいと思います。

f1新しいサブシェルから呼び出されるたびに、f2新しいサブシェルが作成され、3つのコマンドのみが実行されます。

    f1() {
1      if [ "$a" == "" ]; then
2        a="0";
      else
        a=$(($a+1));
      fi;
3      echo "$a";
    }

af1グローバルにし、サブシェルで初期化しました(incrementが繰り返し呼び出されるので、少なくとも私のシステムではa)。ただし、a生成された次のサブシェルには存在しません。

関連情報