[博主公告]

“linux大棚”是一个以Linux技术专题为主的博客。
本博客为了保证读者的浏览体验,决定不刊登任何广告信息。

专题

文章发布时间日历

September 2010
M T W T F S S
« Aug    
 12345
6789101112
13141516171819
20212223242526
27282930  
    <<返回主页

  • 02Jan

    本原创文章属于《Linux大棚》博客,博客地址为http://roclinux.cn。文章作者为rocrocket。
    为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅。

    ===

    [正文开始]

    如果你对子Shell的概念不甚了解,如果你对export的用法还没吃透,如果你不知道Shell如何管理你的变量,请阅读本文。否则,请复习本文。^_^

    情景一:建立一个shell脚本var1.sh,其内容为:

    [rocrocket@rocrocket SHELL]$ cat -n var1.sh
    1    #!/bin/bash
    2    echo :$myvar:

    然后在终端上执行变量赋值语句并用echo显示此变量:

    [rocrocket@rocrocket SHELL]$ myvar=hello
    [rocrocket@rocrocket SHELL]$ echo $myvar
    hello

    但是当执行var1.sh脚本,想显示myvar变量时,情况却并非你所愿:

    [rocrocket@rocrocket SHELL]$ bash ./var1.sh
    ::

    显然,var1.sh并没有看到用户在终端中定义的myvar变量。可见,在终端中设置的变量,在运行的shell脚本中是无法看到的。

    情景二:我们建立一个脚本var2.sh,内容为:

    [rocrocket@rocrocket SHELL]$ cat -n var2.sh
         1	#!/bin/bash
         2	myvar=50
         3	echo :$myvar:

    此时,用户在终端设置myvar的值并显示此值,然后再运行var2.sh,看看结果吧:

    [rocrocket@rocrocket SHELL]$ myvar=100
    [rocrocket@rocrocket SHELL]$ echo $myvar
    100
    [rocrocket@rocrocket SHELL]$ bash var2.sh
    :50:

    可见,终端中设置的值,在shell脚本中是无法改变的;而且,终端也无法改变shell脚本里面设置的变量的值。

    阶段总结:

    在Shell工作机制中,存在一个子shell的概念,上面的两个情景展现的就是子shell的形象。子shell是登录shell为了运行某个脚本程序而建立的一个全新的shell,这个全新的shell只会使用自己的局部变量,对父shell(登录shell)的局部变量不屑一顾。而且,子shell和父shell对对方的局部变量都不会有任何冒犯,井水不犯河水。

    引子:

    有些事情偏偏是需要子shell和父shell有所交互的,这就需要有一个变量是子shell和父shell都能看到和修改的。这时候,export出现了,它可以“导出变量”。

    情景三:建立一个新的shell脚本var3.sh,其内容如下:

    [rocrocket@rocrocket SHELL]$ cat -n var3.sh
         1	#!/bin/bash
         2	echo mylocal=$mylocal
         3	echo myglobal=$myglobal

    在var3.sh脚本中,设置了两个变量,一个是mylocal,表示局部变量,一个是myglobal,表示全局变量。
    在终端上给此两个变量赋值,然后执行脚本程序var3.sh,很明显,结果如你所愿,是空值:

    [rocrocket@rocrocket SHELL]$ mylocal=1
    [rocrocket@rocrocket SHELL]$ myglobal=2
    [rocrocket@rocrocket SHELL]$ bash var3.sh
    mylocal=
    myglobal=

    我们针对myglobal执行export来导出变量,再看看结果:

    [rocrocket@rocrocket SHELL]$ export myglobal
    [rocrocket@rocrocket SHELL]$ bash var3.sh
    mylocal=
    myglobal=2

    看,我们的脚本程序已经看到了myglobal的值了,看来export将myglobal导出,真是起到作用了。

    阶段总结:

    他的内幕是这样的:当使用export来导出一个变量时,当前shell就会将此变量放到“导出变量列表”中,一旦在某个时刻需要建立子shell时,就会将这个导出变量列表拷贝一份给子shell,这样子shell也就有所应当的看到了这些被导出的变量了。

    (为了能让10岁以前小朋友看懂,更形象的说:从前有个母亲叫shell,shell她手里攥着“导出变量列表”和“局部变量列表”两件宝贝,当shell生育了小孩(名叫子shell)的时候,她就把“导出变量列表”这件宝贝复制一份,交给她的孩子,而shell手里的另一件宝贝“局部变量列表”则不会交给小孩)

    引子:

    现在子shell如果想改变这份“导出变量列表”中的某些内容,那么父shell到底能不能察觉呢?父shell会不会随着子shell一起修改这些值呢?

    情景四:看看整个过程:

    [rocrocket@rocrocket SHELL]$ export myglobal=10
    [rocrocket@rocrocket SHELL]$ cat -n var4.sh
         1	#!/bin/bash
         2	myglobal=33
         3	echo myglobal=$myglobal
    [rocrocket@rocrocket SHELL]$ bash var4.sh
    myglobal=33
    [rocrocket@rocrocket SHELL]$ echo $myglobal
    10

    可见,在子shell是无法改变父shell中的“导出变量列表”中变量的值的。子shell只能修改自己手里的那份“导出变量列表”中变量的值。

    阶段总结:

    子shell是无法改变父shell中的“导出变量列表”中变量的值的。
    变量一旦被导出,对所有后续执行的子shell,该变量都是导出变量。

    关于export -p:

    可以执行export -p来查看当前shell的导出变量列表。这其中一定是包括了从父shell继承来的导出变量列表。

    全文总结:

    1 没有导出的变量是局部变量,子shell是看不到的。
    2 导出变量列表被复制给子shell,子shell可以修改和存取它,但是这种修改父shell看不到。
    3 导出变量列表的上述特性对于直接产生的子shell生效,对于由子shell产生的后继子shell也是如此。
    4 export可以在变量赋值之后用,也可以在变量赋值之前用。

    over~

    我猜您对这些文章感兴趣:

    Posted by rocrocket @ 12:53 pm

    Tags: , , , ,

    3,103人阅读过了这篇文章。

    如果您还满意我的文章,请您订阅我的博客。点击“我要订阅”即可。谢谢:)

  • <<返回主页

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.