通常,我会看到有关人们无法从其范围之外访问变量的问题。然而,我似乎正在经历相反的情况:我看到变量仍然具有内部范围的值,他们应该在之后放弃。例如(使svn别名类似于git aliases):
function svn() {
case $@ in
alias*) shift 1;
for i in "$@"; do
if [[ "$i" == "-t" ]];
then
j="$i,$j"
elif [[ "$i" == "-f" ]];
k="$i,$j"
fi
done
echo "i = $i"
echo "j = $j"
echo "k = $k"
;;
esac
}
我把它放在一个脚本中来源,所以它的功能是bash的别名(我想)。尝试使用“-t”和“-f”的各种组合运行它,你会看到变量“$ i”,“$ j”和“$ k”都会在再次运行脚本时保留它们的值,在脚本退出后,它们在外壳中保持不变。我使用的是Ubuntu 15.04笔记本电脑,当我输入Ctrl-X
Ctrl-V
时,我的shell输出GNU bash,版本4.3.30(1)-release(x86_64-pc-linux-gnu)。
我读到的关于bash的一切都告诉我这不应该发生(诚然,我在这方面有点初学者)。在脚本(或函数)退出后,变量不应保持设置,除非您对它们使用export
,我没有。那为什么会这样呢?
答案 0 :(得分:6)
有两种不同的现象:
当变量导出时,会将它们复制到子进程的环境中。未传递未导出的变量。除非您明确使用export
将其标记为导出,否则不会导出变量。
export LESS_OPTIONS=-R # export so `less` sees this variable
less
不要将此与范围混淆,这是不同的。
默认情况下,内部函数变量具有全局范围。您必须使用local
关键字来声明局部变量。否则,像for i in "$@"
这样的循环将修改全局变量$i
,而不是创建局部变量。
svn() {
local i j k
case $@ in
...
esac
}
导出确定子进程看到的内容。范围确定函数是否修改全局变量。