Bash变量作用域泄漏
通常,我会看到人们无法从他们的范围之外访问变量的问题。然而,我似乎遇到了相反的情况:我看到变量仍然有来自内部作用域的值,它们应该在之后放弃。例如(使svn别名类似于): 我把它放在一个脚本中并对其进行源代码转换,所以它的函数被制作成bash的别名(我想)。尝试使用“-t”和“-f”的各种组合来运行此脚本,您将看到变量“$i”、“$j”和“$k”在再次运行脚本时都保持其值,并且在脚本退出后,它们在外壳中保持不变。我使用的是Ubuntu15.04笔记本电脑,当我键入Bash变量作用域泄漏,bash,shell,environment-variables,Bash,Shell,Environment Variables,通常,我会看到人们无法从他们的范围之外访问变量的问题。然而,我似乎遇到了相反的情况:我看到变量仍然有来自内部作用域的值,它们应该在之后放弃。例如(使svn别名类似于): 我把它放在一个脚本中并对其进行源代码转换,所以它的函数被制作成bash的别名(我想)。尝试使用“-t”和“-f”的各种组合来运行此脚本,您将看到变量“$i”、“$j”和“$k”在再次运行脚本时都保持其值,并且在脚本退出后,它们在外壳中保持不变。我使用的是Ubuntu15.04笔记本电脑,当我键入Ctrl-XCtrl-V时,我的s
Ctrl-X
Ctrl-V
时,我的shell输出GNU bash,版本4.3.30(1)-发行版(x86_64-pc-linux-GNU)
我所读到的关于bash的所有信息都告诉我,这种情况不应该发生(诚然,我在这方面是个初学者)。在脚本(或函数)退出后,变量不应保持设置状态,除非对它们使用
export
,我没有这样做。那么为什么会发生这种情况呢?有两种不同的现象在起作用:
export
将变量标记为导出,否则不会导出变量
export LESS_OPTIONS=-R # export so `less` sees this variable
less
不要将其与范围混淆,范围是不同的local
关键字来声明局部变量。否则,类似“$@”中i的循环将修改全局变量$i
,而不是创建局部变量
svn() {
local i j k
case $@ in
...
esac
}
导出确定子进程看到的内容。作用域决定函数是否修改全局变量。这是否在正在运行的脚本中?或者是一个你正在寻找资源然后在命令行上调用函数的文件?第二个。我认为这与范围界定无关。我在互联网上的bash脚本示例中没有看到这一点。因此,在上面的示例中,我会使用类似于
locali=$I
的东西?许多野外编写的脚本都写得很糟糕。他们泄漏变量,他们没有正确引用变量,他们解析ps
和ls
的输出。。。各种各样的胡说八道。在为循环使用之前,有一个正确使用local i
的示例,以及注释,“函数中的局部变量i
与外部脚本中的变量i
存储不同。这允许两个循环在不干扰彼此计数器的情况下运行。”bash的作用域似乎与JavaScript类似。两者都有两种类型的作用域:全局作用域(无标识符)和函数作用域(用var
或local
声明)。我有这个吗?我主要使用JavaScript,所以这样的类比对我很有帮助。是的,你是对的。我从来没有联系过。我想说JavaScript获胜是因为您可以将var
声明放在for
循环中。在bash中,它必须是一个单独的命令。declare
也可以用于作用域。不幸的是,不使用local
或declare
是一个常见错误。
svn() {
local i j k
case $@ in
...
esac
}