如果你对子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可以在变量赋值之后用,也可以在变量赋值之前用。
相关推荐
变量分为不同类型,包括本地变量、环境变量(通过export导出)、局部变量和位置变量(如$1、$2等,其中$0表示脚本本身)。特殊变量如$?表示上一个命令的退出状态,$#表示传递给脚本的参数个数,$*或$@则用来引用所有...
为了使这个文件能够被Shell执行,需要确保其具有执行权限,并且通常将其放置在一个被包含在用户`PATH`环境变量中的目录内。 **数据传递方式**: - **环境变量**: 可以用来设置默认行为或传递配置信息给Shell脚本。 -...
例如,`$color1`脚本无法直接访问父shell的局部变量`color`,但通过`export color`将其导出到环境后,子shell就能识别了。 ```bash $ color=lavender $ cat color1 echo you are now running program: color1 echo ...
普通变量则是局部变量,仅在定义它们的Shell函数或脚本中有效。环境变量需要通过export命令进行导出,使得子进程可以访问。例如,将自定义环境变量NINGJIANCHENG赋值为1的操作是“export NINGJIANCHENG=1”。环境...
变量的生命周期分为局部变量(只在当前Shell会话中存在)和环境变量(可供子进程访问)。可以使用`env`、`set`、`unset`和`export`命令来查看、设置、删除和导出变量。例如,`export`命令可以把一个局部变量提升为...
- **流程控制**:`set -a`选项可以在当前Shell环境中设置自动导出所有局部变量的功能,类似于`export`。 ```bash set -a var1="var1" var2="var2" var3="var3" ``` 使用这种方法,所有定义的变量都会自动导出...
此外,Shell还支持局部变量和全局变量,局部变量仅在定义它们的函数内部可见,而全局变量在整个脚本中都可用。 在控制流程方面,Shell提供了if语句、for循环、while循环和case结构。if语句用于基于条件执行不同的...
需要注意的是,子shell无法访问父shell的局部变量,除非变量被导出到环境(`export color`)。 4. **位置参数与特殊变量** - **位置参数**:在执行脚本时,通过命令行参数传递数据。这些参数可以通过特殊的变量`$1...
- **局部变量**:仅在当前shell或脚本中有效。 - **全局变量**:在整个shell环境中都可见。 - **导出变量**:不仅在当前shell中可见,还能传递给其子shell,从而使这些子shell也能访问这些变量。 #### 四、Export...
使用export命令可以将局部变量导出为环境变量,以便在子进程中使用。 6. exec与source的区别:exec命令在Shell中用于执行文件中的命令,但不会启动新的shell进程,而是用执行的程序替换当前的shell进程。而source...
**本地变量**,也称为局部变量,仅在创建它的Shell脚本或子进程中存在。当Shell脚本执行完毕或者进程结束时,本地变量的值就会消失。设置本地变量使用`$Var-name=value`的方式,如果值包含空格,可以使用双引号括...
- **示例**: 创建一个局部变量并在子Shell中尝试访问它,会发现无法访问。 **3. 环境变量及其设置** - **环境变量**: 在所有用户进程中都可用的变量。 - **作用域**: 包含创建它们的Shell及其所有子Shell或进程。...
2. 全局作用域:在脚本的顶级(非函数内)定义的变量具有全局作用域,可以在整个脚本中被访问,除非被局部变量覆盖。如果在脚本的开头定义了一个变量,那么这个变量在整个脚本中都是可见的。 3. 环境作用域:通过`...
- **普通变量(局部变量)**:只在创建它们的shell函数或脚本中有效。普通变量可以用来存储临时数据或在脚本内使用的特定值。 - **特殊位置参数变量**:如`$1`, `$2`, ..., `$9`, `${10}`, `$#`。其中`$1`, `$2`, .....
Shell中的作业也包含对变量的操作,如使用export关键字将变量导出为环境变量,理解局部变量、环境变量、shell变量之间的区别,以及进行变量替换。变量替换包括文件名替换、参数替换、命令替换、算术替换等,它们允许...
- **局部变量**:`var=value`定义的是局部变量,仅在当前Shell会话中有效。 - **导出变量**:`export var=value`不仅定义了变量,还将该变量标记为全局变量,使得在子Shell或者脚本中也能访问到这个变量。 #### 六...
Shell脚本中的变量有两种类型:局部变量和全局变量。默认情况下,自定义的变量是局部的,只在其定义的函数或脚本块中有效。而通过`export`命令,可以将变量设置为全局变量,使其在子Shell中也能被访问。如果要在父...
关于Shell变量,分为环境变量(全局变量)和局部变量。环境变量定义了Shell的运行环境,通常在用户登录时初始化,如在`.bash_profile`或系统级的配置文件中设置,并使用`export`命令导出。局部变量只在脚本内部有效...
`var=value`定义了局部变量,只在当前Shell会话中有效。`export`则将变量导出,使其成为环境变量,在子进程和新打开的Shell会话中也可访问。 7. **exec与source的区别** `exec`用于执行命令并替换当前Shell进程,...
- **导出变量**:使用`export variable_name=value`将变量设置为环境变量。 - **保留变量**:如`$?`表示上一个命令的退出状态。 - **特殊参数**:如`$0`表示脚本名称,`$1`表示第一个参数等。 **3.3 引号字符** - ...