Linux shell执行source和 . 的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rikeyone/article/details/84573385

一般Linux上执行一个shell脚本,有如下几种方法:

 bash test.sh
 source test.sh
 . test.sh
 ./test.sh

source 和 .

source和 . 这两个都是shell自带的内建命令,这两个命令是等价的关系。也就是说

source test.sh
. test.sh

这两条命令的执行是完全一样的。
使用type来看下命令类型:

xiehaocheng@xiehaocheng:~/work/test/linuxshell$ type source
source 是 shell 内建
xiehaocheng@xiehaocheng:~/work/test/linuxshell$ type .
. 是 shell 内建

使用help来查看命令介绍:

 xiehaocheng@xiehaocheng:~/work/test/linuxshell$ help .
.: . 文件名 [参数]
    在当前 shell 中执行一个文件中的命令。
    
    在当前 shell 中读取并执行 FILENAME 文件中的命令。$PATH 变量中的
    条目被用于寻找包含 FILENAME 文件的目录。如果提供了任何的 ARGUMENTS
    参数,则它们将成为 FILENAME 文件执行时的位置参数。
    
    退出状态:
    返回 FILENAME 文件中最后一个命令的状态;如果 FILENAME 文件不可读则失败。

这两个命令是会由父shell创建子进程去执行shell脚本,并且特别关键的一点,它会继承所有父shell的环境变量。
使用如下命令进行测试:

#!/bin/bash

echo "Print Bash Path:$SHELL"

echo $EXPORT_VAR
echo $LOCAL_VAR

执行如下:

xiehaocheng@xiehaocheng:~/work/test/linuxshell$ LOCAL_VAR=local
xiehaocheng@xiehaocheng:~/work/test/linuxshell$ export EXPORT_VAR=export
xiehaocheng@xiehaocheng:~/work/test/linuxshell$ source test.sh 
Print Bash Path:/bin/bash
export
local
xiehaocheng@xiehaocheng:~/work/test/linuxshell$ . test.sh 
Print Bash Path:/bin/bash
export
local

bash + shell script

使用这种类型的命令,是会显式的调用bash shell作为我们的脚本解释器进行执行,bash需要存在于我们PATH环境变量里。

xiehaocheng@xiehaocheng:~/work/test/linuxshell$ bash test.sh 
Print Bash Path:/bin/bash
export

xiehaocheng@xiehaocheng:~/work/test/linuxshell$ which bash
/bin/bash

当然除了bash,加入我们用于其他类型的shell解释器,也可以使用同样的方法执行脚本。从上面的测试来看,bash + shell script的方式,并不会集成所有的父shell环境变量,但是会继承父shell export出来的环境变量。

./ + shell script

./这个方法在linux世界是用来执行一切可执行文件的方法,不仅仅可以用来执行shell脚本。需要特别注意的是 ./ 并不等于 . 符号,两者是具有本质区别的。
./ 这个符号后面需要跟一个可执行文件的路径,用于定位执行文件的位置,这个路径可以是相对路径。那么如何区分不同的可执行文件呢?对于shell脚本来说,我们会在开头加上:

#! /bin/bash

这个就代表着这是一个需要使用bash shell来进行解释的脚本,当然同样的方式也适用于其他语言,比如python:

#!/bin/python

这里的#!是具有异常魔力的标志,我们叫他magic number。它是用来区分不同类型可执行文件的一种方式。注意#!后面必须要加上对应的解释器路径,并且必须是正确的路径。否则可能会执行失败。

扩展

当然还有一种情况,假如我的系统安装了不同类型shell,那么要如何执行我的脚本使用不同shell来执行呢?实际上脚本中的magic number后指定的只是该脚本默认的执行shell,当我们使用 ./ 来执行时,就会使用默认的shell。如果此时使用显式的方式,那么是会覆盖默认解释器的。
比如我们在脚本中第一行使用mksh作为解释器:

#! /bin/mksh

但是在执行是使用如下命令:

bash test.sh

那么该脚本使用bash shell来运行。
比如我的例子:

xiehaocheng@xiehaocheng:~/work/test/linuxshell$ ./test.sh 
bash: ./test.sh: /bin/mksh: 解释器错误: 没有那个文件或目录
xiehaocheng@xiehaocheng:~/work/test/linuxshell$ bash test.sh
Print Bash Path:/bin/bash
export

由于我的机器没有按照mksh,所以默认查找mksh会失败报错。但是显式告诉系统使用bash来执行,就可以执行成功。

猜你喜欢

转载自blog.csdn.net/rikeyone/article/details/84573385