source 命令与 shell 变量
随着IC工具的升级迭代,不同项目使用到的 IC 工具版本可能会不一样。为保证 IC 工具版本和芯片项目的对应,需要使用 source 命令执行对应项目的环境变量设置脚本。那么,source 命令与一般的脚本执行命令,有什么区别呢?
下面以 bash 环境为例进行详细说明。
1. shell 与局部变量、环境变量
用户登录到 Linux 系统后,可以以终端交互的方式打开一个用户 shell,暂且称之为父shell。在这个shell 中,用户可以使用 shell命令,声明变量,或者运行shell 脚本。
当用户运行 shell 脚本时,系统将创建一个子 shell。子 shell 运行完毕,将返回到之前父shell。一个父shell,可以派生出很多的子 shell。
在父 shell或子 shell 定义的变量只能在当前 shell 中引用。这些变量称之为局部变量。
例如,在一个shell 窗口中运行以下命令:
c="ccc" ; echo $c
显示:
ccc
创建一个脚本c.sh, 内容如下:
#!/bin/bash
echo $c
在当前 shell 中运行此脚本 c.sh,将不会有任何显示:如果父shell 的变量需要被其他子 shell 进行引用、修改,需要使用 export 命令对其进行变量输出。此类变量称为环境变量。环境变量是全局性的。
例如,在shell 窗口中运行以下命令:
export c="ccc" ; echo $c
同样创建脚本c.sh, 内容如下:
#!/bin/bash
echo $c
在当前 shell 中运行此脚本 c.sh,
./c.sh
便会显示变量 c 的值:
ccc
如果 shell 脚本中的变量需要被其他父或子shell 进行引用,除了需要使用 export 命令,还需要使用 source 命令运行脚本文件。这是什么原理呢?
2. source 命令
source命令用于执行shell 类型的脚本文件。
source命令也被称为“点命令”,在bash 中 等同于 "." 命令。例如执行一个脚本文件 test.sh , 以下两行命令是等效的。
. test.sh
source test.sh
对于一个可执行脚本 test.sh,使用 ./test.sh、sh test.sh和 source test.sh 的区别如下:
-
(1) 当 test.sh 脚本具有可执行权限时,./test.sh、sh test.sh 是没有区别的。两者都会创建一个子shell 执行对应的脚本命令。
-
(2) 当 test.sh 没有执行权限时,只能使用 sh test.sh。执行 ./test.sh 命令会报错。
-
(3) source test.sh 只是简单地读取脚本中的命令,并在当前 shell 里执行,并不会创建新的子shell。
总结就是,使用 source 执行脚本文件时,只会在当前shell执行,不会创建新的子 shell,脚本文件中 export 命令对应的变量会输出为全局的环境变量。所以,source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销、重新登录。
例如,shell中创建环境变量 P1,其中冒号“:”表示追加 :
export P1=/test/dir1:/test/dir2”
创建脚本 test.sh:
#!/bin/bash
echo $P1
export P1=$PATH:/test/h3:/test/h4
echo $P1
shell 窗口中运行脚本 ./test.sh,结果如下:
/test/dir1:/test/dir2
/test/dir1:/test/dir2:/test/h3:/test/h4
shell 窗口中运行命令 echo $P1,结果如下:
echo $P1
/test/dir1:/test/dir2
这是因为子shell 中的变量 P1 并不能被父shell 继承。
shell 窗口中使用 source 命令运行脚本 ./test.sh,显示一样的结果
source test.sh
/test/dir1:/test/dir2
/test/dir1:/test/dir2:/test/h3:/test/h4
shell 窗口中再次运行命令 echo $P1,此时结果如下:
echo $P1
/test/dir1:/test/dir2:/test/h3:/test/h4
因为使用 source 命令后,脚本内容在当前shell 中执行,P1 被 export 输出为环境变量,父shell 中可以对 P1 环境变量进行引用。
3. 其他相关命令
(1) C shell 中设置环境变量的方法
setenv P1 "$P1 /test/h3 /test/h4"
(2) 清除环境变量 P1的命令为:
unset P1
(3) 显示所有环境变量
env