购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.3 选择结构

程序设计语言的基础是它们具备对条件进行测试判断的能力,再根据判断结果采取不同的行动,即执行不同的分支语句。同样,Shell程序也具备自己的选择结构,本节向读者介绍Shell程序中可以使用的分支语句,以及使用这些语句的选择结构。

选择程序结构用于判断给定的条件,根据判断的结果来控制程序的流程。在选择结构中,程序的处理步骤出现了分支,它需要根据某一特定的条件选择其中的一个分支执行。选择结构有单选择、双选择和多选择三种形式。

2.3.1 test命令

Shell有一条内部命令test,经常使用它在if语句中测试一种或几种条件。实际上,在大多数的Shell程序中都会大量使用“test”命令(它的另外一种写法是“[ ]”)——即shell的布尔值判断命令。把“[ ]”符号当作一条命令多少有点奇怪,但在实际工作中,这种写法能够使命令的语法看起来更简洁、更明确。test命令的一般格式为:

或者是:

其中,表达式表示要测试的条件,如果为真,则test命令的退出状态为0;如果为假,则test命令的退出状态不为0。

例如,判断环境变量LOGNAME的值是否为zhangfan,如果是,test命令的退出状态为0,否则不为0。首先使用echo命令查看系统的当前用户登录名,命令如下:

或者是:

操作符“=”的作用是测试两个值是否相等。需要注意的是,test将所有的操作数($LOGNAME和zhangfan)和操作符作为单独的参数分别对待,也就是说,它们之间至少要有一个空格符分隔。

所以,在方括号“[ ]”和被判断的条件表达式之间也需要留出空格。读者可以这样记忆,“[”字符和单词“test”的含义是一样的,而单词“test”的后面当然应该有一个空格。

提示

由于test命令在Shell脚本程序以外的程序设计中使用得并不多,所以很多很少编写Shell程序的UNIX/Linux程序员往往会把自己编写的一个简单的小程序命名为“test”(如test.c、test.cpp)。如果一个这样的程序无法正常工作,程序员应该想到它与Shell中的“test”命令重名了。

test命令所判断的表达式通常是一些由Shell命令支持的操作符组合而成的,这些操作符包括字符串操作符、整数操作符、文件操作符、逻辑操作符等。其中,test的字符串操作符的表达方式及test退出状态为0时的条件如表2.4所示。

表2.4 test字符串操作符

整数操作符是一系列进行整数比较的操作符,如表2.5所示。

表2.5 test整数操作符

文件操作是Shell程序中经常使用到的操作,test命令提供了一系列有关文件的处理操作符。这些操作符都是一元的,即都要求带一个参数,并且每个参数都是一个文件名(当然也包括目录文件、链接文件)。test命令所支持的文件操作符如表2.6所示。

表2.6 test文件操作符

例如,判断 /home/zhangfan目录下是否存在sample文件,并判断该文件的属性,可以像下面这样编写Shell程序,读者不妨在自己的Linux主机上试验一下。

另外,这些操作符也可以相互组合,组成更加复杂的条件判断表达式。例如,可以使用逻辑操作符将多个判断表达式连接在一起。test命令所支持的逻辑操作符如表2.7所示。

表2.7 test逻辑操作符

另外,表达式中也可以使用小括号“( )”来改变运算的顺序,这一点和其他高级程序设计语言如出一辙,此处不再赘述。

2.3.2 if语句

单选择结构是最简单的选择结构,如图2.1所示,如果条件满足则执行Shell程序中的命令序列,否则向下到程序出口处。也就是说,当条件不满足时,什么也不执行。Shell程序中用if语句实现这种功能的一般形式为:

if语句的执行过程与if else相似(稍后将会看到),只是在判断条件为“假”时,直接跳过语句序列,执行if的下一条语句。

图2.1 单选择结构

2.3.3 if…else语句

双选择结构如图2.2所示,程序流程出现了两个可供选择的分支,如果条件满足就执行Shell命令序列1,否则执行命令序列2。两个分支中只能选择一条且必须选择一条执行,但无论选择哪一条分支执行,最后流程都一定到达结构的出口处。Shell程序用if…else语句实现这种功能。其一般形式为:

图2.2 双选择结构

2.3.4 if…elif语句

多选择结构如图2.3所示,程序出现多个分支,程序执行方向将根据条件确定。如果满足条件1则执行Shell命令序列1,如果满足条件2则执行命令序列2……如果满足条件N则执行命令序列N。总之,要根据条件选择多个分支中的一个执行,无论选择哪一条分支,最后流程都要到达同一个出口,如果所有分支条件都不满足,则直接到达出口。Shell程序中可以使用if…elif语句实现这种功能,其一般形式为:

图2.3 多选择结构

程序2.4是一个使用if…elif语句实现多分支的示例。程序可根据系统当前时间输出问候语,这里约定从凌晨0点到11点为上午,12点到17点为中午,其他时间为下午。使用date命令可输出当前系统的时间,如下所示:

date命令输出的时间格式是固定的,本程序中只需要取小时的数据,可以观察到显示小时的两位数字总是在date命令结果的第19和20两个字符(当然,不同的系统可能有所差别,如英文版本的Fedora 14)。可以使用管道,将date命令的输出作为cut命令的输入,对时间值进行截取(管道将在第8章讲解),如下所示:

再如,可用下面的方式截取到“小时:分钟:秒”的时间:

事实上,更一般性的做法是使用date命令的选项,这是一种更加简单通用的方法:

代码如程序2.4所示。同样,首先使用touch命令创建一个文本文件greeting.sh,然后使用编辑器打开它,输入程序内容。

【程序2.4】根据系统时间输出问候语:greeting.sh。

保存退出后,使用chmod命令修改文件的执行权限:

运行程序,输出结果如下:

2.3.5 case语句

用嵌套的if语句可以实现多分支结构程序,但分支较多时就显得复杂,可读性差。使用case语句可以将一个值与多个值进行比较,如果发现一项匹配,就执行对应的一条或者一组命令。case语句的调用形式如下:

case语句的作用是当字符串与某个值相同时就执行那个值后面的操作。如果同一个操作对应多个值,则使用“|”将各个值分开。注意,在case的每一个操作的最后面都有两个分号“;;”。

【程序2.5】将输入的数字翻译为英文:translate.sh。

使用chmod命令修改文件的执行权限:

运行程序,输出结果如下:

【程序2.6】输入单个数字或英文字母,判断并输出其类型:judge.sh。

使用chmod命令修改文件的执行权限:

运行程序,输出结果如下: j8IViXe5dz0MqYcjqI1DqoGzh7gsixBjX4MSvbF7AQPQd5984X3Gn7ssQbSlJeRC

点击中间区域
呼出菜单
上一章
目录
下一章
×