All things are difficult before they are easy. 没有软件的裸机是一具僵尸,没有硬件的软件是一个幽灵。2012,专注于Linux和C语言,关注自动化、性能测试,关注开源社区和开源测试工具、方法,尝试测试团队管理!
Shell命名空间(变量作用域)
上一篇 /
下一篇 2011-01-12 00:03:12
/ 个人分类:Shell
以前没有怎么详细关注shell中的命名空间,也就是变量的作用域问题。今天看到一篇文章中提到了,稍微总结一下吧。默认情况下,说Shell,我都以Bash为例。
经常需要在函数中创建环境变量。在大多数编译语言(如
C)中,当在函数内部创建变量时,变量被放置在单独的局部名称空间中。因此,如果在
C 中定义一个名为 myfunction 的函数,并在该函数中定义一个名为 "x"
的自变量,则任何名为 "x"
的全局变量(函数之外的变量)将不受它的印象,从而消除了负作用。
在 C 中是这样,但在 bash 中却不是。在 bash
中,每当在函数内部创建环境变量,就将其添加到全局名称空间。这意味着,该变量将重写函数之外的全局变量,并在函数退出之后继续存在。其实,这个也容易理解的,因为调用函数并没有去新建一个shell,所以它添加的变量也是对这个当前Shell添加的而不仅仅针对这个函数。
举个例子:
#!/bin/bash
myvar="hello" myfunc() { myvar="one two three" for x in $myvar do echo $x > /dev/null done } myfunc echo $myvar $x
|
运行此脚本时,它将输出 "one two three
three",这显示了在函数中定义的 "$myvar" 如何影响全局变量
"$myvar",以及循环控制变量 "$x" 如何在函数退出之后继续存在(如果
"$x" 全局变量存在,也将受到影响)。
我们可以使用不同的变量名来解决这种函数中定义的变量对整个shell的干扰。但这不是正确的方法,解决此问题的最好方法是通过使用 "local" 命令,在一开始就预防影响全局变量的可能性。当使用 "local" 在函数内部创建变量时,将把它们放在局部名称空间中,并且不会影响任何全局变量。这里演示了如何实现上述代码,以便不重写全局变量:
#!/bin/bash
myvar="hello" myfunc() { local x local myvar="one two three" for x in $myvar do echo $x > /dev/null done } myfunc echo $myvar $x |
运行此脚本将输出 "hello" -- 不重写全局变量 "$myvar","$x" 在 myfunc 之外不继续存在。在函数的第一行,我们创建了以后要使用的局部变量 x,而在第二个例子 (local myvar="one two three"") 中,我们创建了局部变量 myvar, 同时 为其赋值。在将循环控制变量定义为局部变量时,使用第一种形式很方便,因为不允许说:"for local x in $myvar"。此函数不影响任何全局变量,鼓励您用这种方式设计所有的函数。只有在明确希望要修改全局变量时,才不应该使用 "local"。
今后写shell的函数时也要注意这个细节哦。
另外,这里提到函数,顺便补充一句:可以将函数(如上面的函数)放在 ~/.bashrc 或 ~/.bash_profile 中,以便在 bash 中随时使用它们(像使用一个bash命令一样)。
参考资料:http://www.ibm.com/developerworks/cn/linux/shell/bash/bash-2/
收藏
举报
TAG:
BASH
bash
Bash
shell
Shell
变量
函数
命名空间
作用域