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 变量 函数 命名空间 作用域

 

评分:0

我来说两句

smile665

smile665

Stay hungry, stay foolish. 得意之时谨记,一半命运还掌握在上帝手里;失意之时须知,一半命运还掌握在自己手里。

日历

« 2024-04-26  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 955845
  • 日志数: 220
  • 建立时间: 2008-11-06
  • 更新时间: 2012-10-06

RSS订阅

Open Toolbar