什么时候变量是局部变量,什么时候是全局变量?

什么时候变量是局部变量,什么时候是全局变量?

考虑以下两个函数:

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

但如果我f1f2 a遗骸中打电话0

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

我听说(也经历过)函数中声明的变量是全局的。那为什么会有这样的差异呢?这是特殊情况还是我没有f1f2正确的方式调用?

好的,我刚刚注意到将f2定义更改为:

f2() {
  eval "$1";
}

解决了问题,但了解第一种调用的目的是什么仍然很有趣$($1)。它到底有什么作用?

我还注意到我无法将 的“返回”值分配f1给 中的变量f2

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

res每次调用后都会相同f2 "f1"

为什么?

答案1

在 f1 中, 的值a是全局的(在 bash 中),如果a定义为:

local a

将 f1 定义更改为:

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

使变量成为局部变量。

对于 f2:在子 shell $(f2) 中调用 f2。子 shell 变量不会影响父 shell。

答案2

我要感谢任何提到 subshel​​l 的评论。不过我想给出更详细的答案。

每次f1从新的子 shell 调用时f2,都会创建一个新的子 shell,并且只会执行 3 条指令。

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

a变为全局并在子 shell 中初始化(至少在我的系统上,因为重复f1调用increment a)。但a在下一个创建的子 shell 中不存在。

相关内容