Shell中的流程控制
前面我们实现了Shell的两个主要功能:运行命令和处理命令行。现在我们来简单实现Shell的第三个功能——可编程。任何一种编程语言都需要对流程进行控制,Shell也不例外,这里就简单实现在Shell中如何提供if控制语句。Shell中的if语句的作用与其他语言的if语句相同:条件检测。如果条件为正值,则有一部分代码被执行。不过这里有一点与其他语言不同,在Shell中,if语句有以下特点:
1、条件是一个命令,返回正值意味着命令运行成功。
2、exit(0)代表成功。
3、如果if后的条件是一系列的命令,那么最后一个命令的exit值被用作这个语句块的条件值,并由此来决定条件是否成立。
在Shell中if的工作流程主要如下:
1、Shell运行if之后的命令
2、Shell检查命令的exit状态
3、exit的状态为0意味着成功,非0意味着失败
4、如果成功,Shell执行then部分的代码
5、如果失败,Shell执行else部分的代码
6、关键字fi标识if块的结束
在Shell中增加if
现在已经知道if控制语句做什么,也知道它是如何工作的。那么如何在Shell中增加if语句呢?在前面的版本中,Shell的控制流从splitline直接到fork,每个命令都被直接传给exec。新增if语句后命令处理变得复杂,我们这里用process函数来处理。
process将脚本看作一个接一个的代码区域。第一个区域是then代码块,第2个区域是else代码块,第3个是在if语句之外的代码块。如下图所示,
114.jpg
对于不同的区域,Shell的处理方法是不同的。
1、if语句之外的区域,称为中立区。对于这类区域的代码,简单地度一条,分析一条,执行一条。
2、if和then之间的区域。这个区域中,Shell每执行一条命令就记录下它的退出状态
3、then到fi或else之间的区域。这个区域中,Shell如果遇到if语句就重复第2个处理方法。
4、else到fi之间的区域。在fi后又回到中立区。
Shell记录当前区域类型,还必须记录在WAIT_THEN区域中执行命令的结果。不同区域的处理方法不同,特定的区域与程序的特定状态联系在一起。proces通过3个函数来处理区域问题。
is_control_command返回一个布尔变量告诉process这条命令是脚本语言的一部分还是一条可执行的命令。
do_control_command处理关键字if、then和fi,每个关键字都是区域的界标。这个函数更新状态变量并执行必要的操作。
ok_to_execute根据当前的状态和条件命令的结果返回一个布尔值,说明能否执行当前命令。
下面是程序运行结果和源码(这里把原来一个文件分割成了几个文件):
121.jpg
点击此处下载ash.rar (文件大小:3K)