Skip to content

Source、bash、sh、.的区别

Linux 一个shell命令窗口,就是Linux系统的一个shell进程,如果打开命令窗口就是多个shell进程,每个进程都有自己独立的的环境,比如使用env命令查看到的就是当前窗口进程的环境变量。在这个窗口下通过命令运行起来的程序(比如一些Linux命令,如ls命令或./ext_file 命令,命令即程序),就是该shell窗口进程的子进程,子进程会继承父进程的环境,即继承env环境变量(非export类型的变量不继承)。

test.sh

1
2
3
4
#加一个环境变量test,赋值666
export test=666 
#查看一下此时shell进程的环境变量
env

1 source

source是在当前进程(终端)下执行脚本。source test.sh 等价于  . test.sh

执行这个命令时,并非创建子进程,test.sh内容是在当前的shell进程执行,即会在当前进程生效,执行之后,test.sh中env命令显示的是当前进程进程的环境变量,确实添加了 test=666。

在终端中输入env,还是有test环境变量,这是因为是在当前进程下创建的

用途:给当前命令窗口进程,添加环境变量,比如Make的编译环境配置,可以通过命令一个一个变量添加,麻烦,一般都写在一个xxx.sh文件中,通过 source xxx.sh统一添加。xxx.sh不需要有”执行权限”

2 ./、sh、bash

这三个命令都是新开一个子进程执行命令。(子进程可以继承父进程的环境变量,但是父进程看不到子进程的环境变量)

如果我直接运行./test.sh(需要有可执行权限),首先你会查找脚本第一行是否指定了解释器,如果没指定,那么就用当前系统默认的shell(大多数linux默认是bash),如果指定了解释器,那么就将该脚本交给指定的解释器.比如

1
2
#!/usr/bin/python
#!/usr/bin/bash

执行./test.sh这个命令时(先用unset test删除环境变量),会基于当前窗口shell进程,创建一个子进程,test.sh内容是在子进程中执行并生效,test.sh中的env命令显示的是子进程的环境变量,子进程中确实添加了test=666。

但此时再用命令env查看环境变量(此时是父进程),里边没有test=666变量

sh 、bash命令与./ 一样,都是创建子进程。只不过这两个专用于执行sh脚本,而./命令可用于所有可执行文件(sh、bin文件)