前些天在装opencl的beignet实现版本时,发现wiki中里面有个点命令.,不知道具体含义就百度了下,结果学了一些相关的知识,记录如下。
source
命令是bash的内置命令,与点命令.等效,唯一不同的是点命令是在POXIS下定义的]。source
命令的执行格式是source script
,是在当前shell进程中依次执行script文件中的语句。那么与普通的 sh script
和./script
有什么不同呢?主要有两个不同点:
source
的执行是在当前进程中执行,而sh script
和./script
在执行的时候,当前进程会开辟一个新的子进程,然后在子进程中执行script中的语句。source
命令的文件不需要有执行权限,而./script方式执行的方式需要script文件有可执行权限(注意:sh script
不需要script文件有可执行权限)。我们可以举几个例子来展示上面提到的不同点(例子都摘自参考内容中的第1个链接)。
编写脚本test.sh如下:
echo $$
需要说明一下,在Linux中,每个进程都有一个独一无二的进程号,简称为PID
。而$$
就表示当前进程的PID
。所以上述脚本的作用就是输出当前进程的PID
。
我们可以用两种方式来执行这个脚本,先使用source
命令来执行:
> source test.sh
3824
> source test.sh
3824
> source test.sh
3824
可以看到每次输出的结果都是3824。然后使用sh script
方式来执行:
> sh test.sh
3884
> sh test.sh
3889
> sh test.sh
3894
可以看到每次输出的结果都在改变。
这个测试说明:使用source
命令在当前进程执行,而使用sh script
命令则每次执行时都生成不同的子进程,在子进程中执行,执行完后面文件中的指令后再返回主进程。
编写测试脚本test.sh
:
echo "FOO:"$(env | grep FOO)
export FOO=foo
echo "FOO:"$(env | grep FOO)
echo "PWD:"$PWD
cd mydir
echo "PWD:"$PWD
这个脚本先是测试环境变量中是否包含名为FOO
的环境变量,然后新建的环境变量Foo=foo
。然后是输出当前所在目录,接着切换到当前目录的mydir
子目录,然后再输出当前所在目录。
在执行这个脚本前,我们先检查下当前环境:
> env | grep FOO
> echo $PWD
/home/yunfeng
这说明当前环境中没有名为FOO
的变量,当前所在路径为/home/yunfeng
。
然后我们执行sh test.sh
,输出为:
FOO:
FOO:FOO=foo
PWD:/home/yunfeng
PWD:/home/yunfeng/mydir
然后我们再检查下当前环境:
> env | grep FOO
> echo $PWD
/home/yunfeng
这说明使用sh test.sh
执行的时候,并没有改变当前进程的环境变量和所在路径,而只是改变了新建的子进程的环境变量和所在路径。此外我们还可以得出结论:当前进程新建shell子进程的时候为子进程复制了当前进程的环境变量(包括路径)。
然后使用source
命令执行test.sh
:
source test.sh
FOO:
FOO:FOO=foo
PWD:/home/yunfeng
PWD:/home/yunfeng/mydir
然后检查当前环境:(其实可以发现,当前目录已经切换到mydir
了)
> env | grep FOO
FOO=foo
> echo $PWD
/home/yunfeng/mydir
可以看出使用source
命令时,会改变当前进程的环境变量。