在linux找那个我们有时会需要设置一些环境变量来方便我们的工作,永久生效,暂时生效,全局生效,当前环境有效,激活隔离环境等,这就用到了export,source
父shell与子shell
首先说明两个概念:
父shell与子shell,从shellA中启动一个shell,称之为shellB。shellA为父shell,shellB为子shell。
最容易理解的情况就是在一个shell中执行一个gnome-terminal命令(不同桌面环境命令不一样),弹出一个新的shell
最常见的情况是在当前shell下执行shell脚本,这个脚本实际上是在子shell中执行的
环境变量与局部变量
环境变量在全局都有效,而局部变量只在当前shell中有效
linux中export命令:
将局部变量申明为环境变量
用法如:export JAVA_HOME=/opt/jdk
Linux source命令:
用法:source filepath
或 . filepath
功能:使当前shell读入路径为filepath的shell文件并依次执行文件中的所有语句,通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。例如,当我们修改了/etc/profile文件,并想让它立刻生效,而不用重新登录,就可以使用source命令,如source /etc/profile
。
source命令(从 C Shell 而来)是bash shell的内置命令;点命令(从Bourne Shell而来)是source的另一名称。这从用法中也能看出来。
source filepath
与 sh filepath
、./filepath
的区别:
- 当shell脚本具有可执行权限时,用
sh filepath
与source filepath
,./filepath
是没有区别的。
[root@localhost scripts]# chmod +x test.sh
[root@localhost scripts]# . test.sh
hello,world
[root@localhost scripts]# source test.sh
hello,world
[root@localhost scripts]# sh test.sh
hello,world
[root@localhost scripts]# . ./test.sh
hello,world
[root@localhost scripts]# source ./test.sh
hello,world
[root@localhost scripts]# sh ./test.sh
hello,world
[root@localhost scripts]# ./test.sh
hello,world
[root@localhost scripts]#
注意.
命令与路径中的.
(代表当前路径)不一样
-
sh filepath
会重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的,改变的变量不会被带回父shell,除非使用export。 -
source filename其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell中。
source用法举例说明:
[root@localhost scripts]# vim demo.sh
[root@localhost scripts]# cat demo.sh
A=1
[root@localhost scripts]# chmod +x demo.sh
[root@localhost scripts]# ll
total 16
-rwxr-xr-x. 1 root root 4 Aug 1 14:42 demo.sh
-rw-r--r--. 1 root root 18 Aug 1 14:07 exp1.sh
-rw-r--r--. 1 root root 29 Aug 1 14:08 exp2.sh
-rw-r--r--. 1 root root 10 Aug 1 14:08 test.sh
[root@localhost scripts]# sh demo.sh
[root@localhost scripts]# echo $A
[root@localhost scripts]# ./demo.sh
[root@localhost scripts]# echo $A
[root@localhost scripts]# . demo.sh
[root@localhost scripts]# echo $A
1
[root@localhost scripts]# unset A # unset的作用为删除指定变量
[root@localhost scripts]# echo $A
[root@localhost scripts]# source demo.sh
[root@localhost scripts]# echo $A
1
[root@localhost scripts]#
实验验证
这里用最常见的情况举例:在当前shell下执行脚本
现在有三个脚本
exp1.sh
内容为
var="hello,world"
exp2.sh
内容为
var="hello,world"
export var
test.sh
内容为
echo $var
实验1:
[root@localhost scripts]# ll
total 12
-rw-r--r--. 1 root root 18 Aug 1 14:07 exp1.sh
-rw-r--r--. 1 root root 29 Aug 1 14:08 exp2.sh
-rw-r--r--. 1 root root 10 Aug 1 14:08 test.sh
[root@localhost scripts]# source exp1.sh
[root@localhost scripts]# echo $var
hello,world
[root@localhost scripts]# bash test.sh
[root@localhost scripts]#
实验2:
[root@localhost scripts]# ll
total 12
-rw-r--r--. 1 root root 18 Aug 1 14:07 exp1.sh
-rw-r--r--. 1 root root 29 Aug 1 14:08 exp2.sh
-rw-r--r--. 1 root root 10 Aug 1 14:08 test.sh
[root@localhost scripts]# source exp2.sh
[root@localhost scripts]# echo $var
hello,world
[root@localhost scripts]# bash test.sh
hello,world
[root@localhost scripts]#
可以看到执行exp脚本之后,在当前shell下执行echo $var
是可以输出var
的值的,因为source
会读取exp脚本的内容并执行文件中的语句,使var在当前shell中有值。
执行bash test.sh
时,实验1是没有任何输出,因为在执行test脚本产生的子shell中找不到var这个变量;而实验2 echo出了var的值,因为实验2中exp2.sh加入了export,所以var变成了环境变量(全局有效),所以var对子shell是可见的,而实验1中由于没有export var,所以var是个局部变量,并不能被子shell看到。
同样的,linux中在 profile
,bashrc
或者其他类似的文件中设置环境变量时(比如PATH),如果没有export,那么只能在当前shell中起作用;如果在当前shell下运行脚本或者直接启动一个子shell,因为设置变量的是局部变量,那么在子shell中该变量没有值。
参考:https://blog.csdn.net/damontive/article/details/50352722