shell脚本编程初识—解释器原理

一. 初识shell脚本

1. 重识shell

(1)shell是一个用C语言编写的程序,它是与Linux内核沟通的桥梁。shell即是一种命令语言,也是一种程序化语言。
(2)shell是指一种应用程序,是一种与内核沟通的外壳应用程序,shell有时提供一个界面,用户通过界面访问操作系统内核服务。
(3)shell可以看作是和Linux内核沟通的媒婆,而bash则是媒婆中的王婆(媒婆的一个特定人物)。

2. 初识shell脚本语言

shell脚本语言

(1)shell脚本(shell script),是一种为shell编写的脚本程序。
(2)业界所说的shell通常指shell脚本。所说的shell编程,通常是指shell脚本编程,并不是指开发shell本身。

shell开发环境

(1)shell脚本的编程和Java,PHP等语言类似,只需要编写代码的文本编辑器和解释代码的解释器就可以了。
(2)Linux 的 Shell 解释器种类众多,常见的有: Bourne Shell(/usr/bin/sh或/bin/sh)、 Bourne Again Shell(/bin/bash)、 C Shell(/usr/bin/csh)、 K Shell(/usr/bin/ksh)、 Shell for Root(/sbin/sh)等。
(3)我们通常用的解释器为bash,即 Bourne Again Shell(/bin/bash)。

shell脚本语言的特点

(1)解释非编译型——即利用解释器解释代码,而不编译。
(2)弱类型——即对于变量不区分变量类型,统一当成字符串看待。
(3)执行模式——交互式(命令行命令)和批处理式(shell脚本)。

3. 编写简单的shell脚本语言及认识解释器原理

一个简单的shell脚本语言

 #!/bin/bash
echo "hello world!" 

对于上述代码:
(1)#!表示shabang,后面跟解释器。告诉系统这个程序用什么解释器解释。
(2)echo用于向窗口输出文本。

执行方式

(1)作为可执行程序

 # chmod +x test.sh
 # ./test.sh 
 hello world!

执行原理:第一条命令是为程序加上可执行权限;
第二条命令是运行可执行程序,注意必须加上./(当前目录下的程序),否则系统会找不到程序的所在位置。
(2)作为解释器参数

 #/bin/bash test.sh
  hello world!

执行原理:直接运行解释器,其参数就是shell脚本的文件名,此时不需要在shell脚本中写第一行的解释器种类,写了也没用。

注:shell脚本中用#作为注释符号,与C/C++的//的作用相同。但是第一行的#不表示以上意思,表示shabang。

(2) shell解释器原理

对于第一种可执行方式:
正常情况下:shell会fork创建子进程,并调用exec执行 ./test.sh这个程序,exec系统调用应该把子进程的代码段替换成./test.sh的代码段,并从它的_start开始执行。
但是./test.sh作为文本程序,没有_start函数。但是exec有另外一种机制,如果要执行的是一个文本文件,并且第一行有shabang指明了解释器,则用解释器代码段替换当前进程。并且从解释器的 _start函数开始执行。而这个文本文件被当作命令行参数传递给解释器,解释器对文本文件进行解析。

(3)利用解释器原理解释程序

# cat test.sh 
#!/bin/bash
pwd 
cd .. 
pwd 
# ./test.sh
/home/hb/test-shell 
/home/hb 
# pwd 
/home/hb/test-shell

为什么在程序中切换到了上一级目录,而且程序运行结果也是这样。
但是在命令行查看当前目录却没有切换到上级目录???

答:根据bash的执行原理,bash会先创建子bash并调用exec来执行shell脚本程序。而子bash和父bash(子进程和父进程)是相互独立的,子bash的改变不会影响到父bash的改变,所以在命令行执行pwd命令,还是当前目录。
# pwd 
/home/hb/test-shell 
# cd .. 
# pwd 
/home/hb

直接命令行上执行 cd 命令,发现父bash的工作目录发生了改变!为什么利用上述原理不能解释这个现象呢???

答:并不是执行所有的命令都需要创建子进程,对于像cd这样的内置命令,就像执行bash自己的内置函数一样,直接由bash执行内置命令。
# cat test.sh 
#!/bin/bash 
pwd 
cd .. 
pwd 

# pwd 
/home/hb/test-shell 

# source test.sh 
/home/hb/test-shell 
/home/hb 

# pwd 
/home/hb

# . test.sh 效果一样 

在命令行执行第一个pwd时,查看当前所在目录。
在执行./test.sh时,前面加上source命令,执行完成,输出执行结果。
再在命令行执行pwd时,查看当前所在目录,目录切换至上一级目录。说明shell脚本将目录改变了,这又是为什么呢?

答:source命令,.命令等也是shell的内置命令,这种方式 也不会创建子Shell,而是直接在交互式Shell下逐行执行脚本中的命令。

你可能感兴趣的:(shell)