我们先来看一个操作, 为了便于说明, 我就直接在命令后面进行注释, 并以#开头
[taoge@localhost Desktop]$ echo $$ # 查阅当前shell进程的进程号码
2455
[taoge@localhost Desktop]$ cat a.sh # 查阅a.sh中的内容
#! /bin/bash
echo "shell script"
x="good x"
[taoge@localhost Desktop]$ ./a.sh # 执行./a.sh
shell script
[taoge@localhost Desktop]$ echo $x # 看一下x的值, 结果发现x没有值, 为什么呢? 因为子的变量没有到父中
[taoge@localhost Desktop]$ source ./a.sh # 用source执行一下./a.sh, 意味着把子的变量导入到父中
shell script
[taoge@localhost Desktop]$ echo $x # 在父中查看一下x, 果然有值了
good x
[taoge@localhost Desktop]$ bash # 进入子bash shell
[taoge@localhost Desktop]$ echo $$
2592
[taoge@localhost Desktop]$ echo $x # 看一下子bash shell中的x, 发现没有, 因为父shell中的x不是“临时环境变量”, 而是普通变量, 在子bash shell中不生效
[taoge@localhost Desktop]$ exit # 退出到父shell中
exit
[taoge@localhost Desktop]$ export x # 将父shell中的普通变量x变为“临时环境变量”x
[taoge@localhost Desktop]$ bash # 再次进入子bash shell
[taoge@localhost Desktop]$ echo $$
2613
[taoge@localhost Desktop]$ echo $x # 查阅x, 发现有值了
good x
[taoge@localhost Desktop]$ exit
exit
[taoge@localhost Desktop]$ echo $$ # 再次退出到父shell中
2455
[taoge@localhost Desktop]$
从上面的操作和结果, 我们可以看到: 单纯执行shell脚本./a.sh, 并不能把脚本中定义的变量导入到父shell中, 必须用source的方式执行才可以。
还有一个问题, 从上面我们可以看到, source ./a.sh后, x在父shell中仍然是普通变量, 需要export变为“临时环境变量”, 多了一步人为操作, 多不爽啊。 其实, 我们完全可以在a.sh中先用export, 如下:
[taoge@localhost Desktop]$ echo $$
2455
[taoge@localhost Desktop]$ cat a.sh
#! /bin/bash
echo "shell script"
export y="good y"
[taoge@localhost Desktop]$ ./a.sh
shell script
[taoge@localhost Desktop]$ echo $y
[taoge@localhost Desktop]$ source ./a.sh
shell script
[taoge@localhost Desktop]$ echo $y
good y
[taoge@localhost Desktop]$ bash
[taoge@localhost Desktop]$ echo $$
2792
[taoge@localhost Desktop]$ echo $y # 有值了!!!
good y
[taoge@localhost Desktop]$ exit
exit
[taoge@localhost Desktop]$ echo $$
2455
[taoge@localhost Desktop]$
可以看到, 实现了我们预期的结果。
最后总结一下:单纯执行shell脚本./a.sh, 并不能把脚本中定义的变量(普通变量或“临时环境变量”)导入到父shell中, 必须用source的方式执行才可以把变量(普通变量或“临时环境变量”)导入到父shell中。 这么看起来, export和source颇有点“相反"的感觉。
在实际的linux软件开发过程中, export和source到处可见。