首先,我们要了解shell脚本是一种脚本语言,他不需要编译,而是直接运行解释器,将脚本作为解释器程序的参数运行的。

我们用不同方法执行名为test.sh的脚本。

bash

用bash执行,就是用/bin/bash这个程序去做解释器解析脚本,这个程序也是当前的默认shell:

[root tmp]#echo $SHELL
/bin/bash

既然用/bin/bash登录上来的,那么当前用户对/bin/bash肯定是有执行权限的,我们来看下:

[root tmp]#ll /bin/bash
-rwxr-xr-x. 1 root root 942200 3月 23 08:15 /bin/bash

所以用bash执行脚本,test.sh作为参数,不管test.sh有没有执行权限都可以执行的;

bash是一个程序,执行是要开一个进程的,他在当前的shell中执行的程序,所以打开的新进程为当前shell进程的子进程(名字为bash),在子进程中定义的本地变量是不会影响到父进程的,除非用export将变量设为环境变量。

.或者source

这两个命令是shell内建的命令,用type看一下:

[root tmp]#
[root tmp]#type .
. is a shell builtin
[root tmp]#type source
source is a shell builtin

所以他们的权限继承的是/bin/bash的权限,在执行时也是将test.sh作为参数,并不需要test.sh有执行权限;

和bash执行不一样的是,source和.不会创建子进程,是在当前shell进程下执行的,因为他们是内建命令,所以脚本中赋值的本地变量也会影响当前shell的,用的时候一定要注意。

文件名直接执行

用文件名直接执行时不是把脚本当做参数了,而是一个可执行程序,所以需要执行权限,而且不写相对路径或者绝对路径时,如果从PATH变量中没有找到当前路径,系统就会提示找不到文件;

由于脚本本身作为可执行程序,所以是会创建名为脚本名(test.sh)的子进程。

shebang

脚本前加的shebang的作用是指明执行这个脚本文件的解释程序。

用bash和source或者.执行时候,因为是将脚本作为参数,所以会直接使用bash(用别的shell就变成别的解释器程序)这个程序作为解释程序而不去看shebang.但是直接脚本名执行时,不写shebang系统会默认使用当前shell来执行。

总结

选项

bash

.或source

文件名

脚本执行权限

不需要

不需要

需要

子进程

创建

不创建

创建

shebang

不使用

不使用

使用