Shell脚本的执⾏过程、执⾏⽅式详解
当Shell脚本运⾏时,它会先查系统环境变量ENV,该变量指定了环境⽂件(加载顺序通常是/etc/profile、~/.bash_profile、
~/.bashrc、/etc/bashrc等),在加载了上述环境变量⽂件后,Shell就开始执⾏Shell脚本中的内容。
Shell脚本是从上⾄下、从左⾄右依次执⾏每⼀⾏的命令及语句的,即执⾏完了⼀个命令后再执⾏下⼀个,如果在Shell脚本中遇到⼦脚本(即脚本嵌套)时,就会先执⾏⼦脚本的内容,完成后再返回⽗脚本继续执⾏⽗脚本内后续的命令及语句。
通常情况下,在执⾏Shell脚本时,会向系统内核请求启动⼀个新的进程,以便在该进程中执⾏脚本的命令及⼦Shell脚本,基本流程如图:
Shell脚本的执⾏通常可以采⽤以下⼏种⽅式:
1)bash script-name或sh script-name
这是当脚本⽂件本⾝没有可执⾏权限(即⽂件权限属性x位为-号)时常使⽤的⽅法,或者脚本⽂件开头没有指定解释器时需要使⽤的⽅法;
举例说明:
[root@localhost ~]# vim test.sh
echo 'this is a shell scripts!'
[root@localhost ~]# sh test.sh
this is a shell scripts!
[root@localhost ~]# bash test.sh
this is a shell scripts!
2)path/script-name或./script-name
指在当前路径下执⾏脚本(脚本需要有执⾏权限),需要将脚本⽂件的权限先改为可执⾏(即⽂件权限属性加x位),具体⽅法为chmod+x script-name。然后通过脚本绝对路径或相对路径就可以直接执⾏脚本了;
举例说明:
[root@localhost ~]# ./test.sh
-bash: ./test.sh: 权限不够
[root@localhost ~]# chmod u+x test.sh
[root@localhost ~]# ./test.sh
this is a shell scripts!
这种⽅法⽐较⿇烦⼀些!每次编写完脚本都必须给脚本⼀个执⾏的权限,否则将会提⽰“权限不够”的错误。
3)source script-name或.script-name
这种⽅法通常是使⽤source或“.”(点号)读⼊或加载指定的Shell脚本⽂件(如san.sh),然后,依次执⾏指定的Shell脚本⽂件san.sh中的所有语句。这些语句将在当前⽗Shell脚本father.sh进程中运⾏(其他⼏种模式都会启动新的进程执⾏⼦脚本)。因此,使⽤source或“.”可以将san.sh⾃⾝脚本中的变量值或函数等的返回值传递到当前⽗Shell脚本father.sh中使⽤。
举例说明:
[root@localhost ~]# chmod u-x test.sh
[root@localhost ~]# ll test.sh
-rw-r--r--. 1 root root 32 8⽉  26 03:09 test.sh
[root@localhost ~]# . test.sh
this is a shell scripts!
[root@localhost ~]# source test.sh
this is a shell scripts!
4)sh<script-name或cat scripts-name|sh
同样适⽤于bash,不过这种⽤法不是很常见,但有时也可以有出奇制胜的效果,例如:不⽤循环语句来实现精简开机⾃启动服务的案例,就是通过将所有字符串拼接为命令的形式,然后经由管道交给bash操作;
举例说明:
[root@localhost ~]# ll test.sh
-rw-r--r--. 1 root root 32 8⽉  26 03:09 test.sh
[root@localhost ~]# sh<test.sh
this is a shell scripts!
[root@localhost ~]# cat test.sh|bash
this is a shell scripts!
⼀个简单的例⼦明⽩第三种执⾏⽅式的特殊性:
[root@localhost ~]# echo 'user=`whoami`' > test2.sh
[root@localhost ~]# cat test2.sh
user=`whoami`
[root@localhost ~]# sh test2.sh
[root@localhost ~]# echo $user
[root@localhost ~]# . test2.sh
[root@localhost ~]# echo $user
root
本⼈亲⾃尝试得出的结论有三点:
1.⼦Shell脚本会直接继承⽗Shell脚本的变量、函数(就好像是⼉⼦随⽗亲姓,基因也会继承⽗亲的)等,反之则不可以;
2.如果希望反过来继承(就好像是让⽗亲随⼉⼦姓,让⽗亲的基因也继承⼉⼦的),就要⽤source或“.”在⽗Shell脚本中事先加载⼦
Shell脚本;
3.通过source或“.”加载执⾏过的脚本,由于是在当前Shell中执⾏脚本,因此在脚本结束之后,脚本中的变量(包括函数)值在当前
Shell中依然存在,⽽sh和bash执⾏脚本都会启动新的⼦Shell执⾏,执⾏完后退回到⽗Shell。因此,变量(包括函数)值等⽆法保留。
shell最简单脚本在进⾏Shell脚本开发时,如果脚本中有引⽤或执⾏其他脚本的内容或配置⽂件的需求时,最好⽤“.”或source先加载该脚本或配置⽂件,处理完之后,再将它们加载到脚本的下⾯,就可以调⽤source加载的脚本及配置⽂件中的变量及函数等内容了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。