考虑以下两个函数:
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)
。它到底有什么作用?
我还注意到我无法将 的“返回”值分配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
我要感谢任何提到 subshell 的评论。不过我想给出更详细的答案。
每次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 中不存在。