条件测试和捕获信号


一、退出状态

在Linux系统中,无论是命令、脚本还是程序,执行完成退出后都存在退出状态,退出状态通常保存在预定义变量$?中。大多数情况下,预定义变量只会使用两个数字表示命令、脚本和程序的退出状态。

数字0表示命令、脚本或程序成功执行,没有发生错误。

数字1表示在执行过程中发生了某些错误,没有成功执行。

由于退出状态由程序编写者定义,因此退出状态也可能不是0或1,遇到这种情况时,可能需要查阅其说明文件了解具体含义。

说明:虽然退出状态的值可能会有许多,但只要退出状态不是数字0,就可以认为程序、命令发生了错误。

【设置退出状态命令】

在编写较为复杂的脚本时,应该考虑错误捕捉机制,即当脚本中的语句执行出现错误时,脚本能够处理错误。一个简单的例子:如果用户使用脚本没有给出必要的参数,脚本应该能够检查到这个错误,并提示用户。

在脚本中设置退出状态需要使用exit命令,其常见的使用形式及对应的含义如下:

exit 0:表示返回脚本执行成功,无错误返回。这种情况有时也称为返回为真(true)。

exit 1:表示执行失败,有错误返回。这种情况有时也称为返回为假(false)。

除了以上的0和1之外,还可以使用其他一些数字,但只要返回的状态非0,系统就认为脚本执行失败。

使用exit命令设置退出状态时需要注意,无论脚本执行到何处,只要遇到exit命令,脚本会立即设置退出状态并退出脚本。

注意:函数返回状态命令return与退出状态命令exit的区别:exit直接退出程序,后面不再执行;return只是所在函数返回,后面会继续执行。

二、文件测试

对文件的测试包括两个方面:(1)文件基本测试,包括文件、目录是否存在、文件类型、文件长度等;(2)文件权限测试,包括文件是否可读、可写、可执行等。

1、文件基本测试

文件基本测试大多用在创建文件、目录之前,这样做的目的是让脚本拥有更好的容错性。

【文件测试命令】

文件基本测试常用的命令及其含义如下:

d:测试目标是否存在,并且是一个目录。

f:测试目标文件是否存在,并且是一个普通文件。

L:测试目标文件是否存在,并且是一个链接文件。

b:测试目标文件是否存在,并且是一个块设备文件。

c:测试目标文件是否存在,并且是一个字符设备文件。

e:测试指定文件或目录是否存在。

S:测试目标文件是否存在,并且是一个Socket文件。

p:测试目标文件是否存在,并且是一个FIFO(pipe)文件。

【文件测试命令的格式】

[ -command parameter ]

上面的基本格式中,command为测试命令,parameter是需要测试的目标文件或目录。需要注意的是,文件测试的命令、参数都要放在中括号内。

注:条件测试命令允许在命令提示符下使用。

注意:与C语言类似,在shell脚本中也使用数字0表示真,非0数字表示假。

2、文件权限测试

【文件权限测试命令】

常用的文件权限测试命令及其含义如下:

w:判断指定的文件是否存在,并且拥有可写入权限。

r:判断指定的文件是否存在,并且具有可读取权限。

x:判断目标文件是否存在,并且具有可执行权限。

u:判断目标文件是否存在,并且具有SUID属性。

g:判断目标文件是否存在,并且具有SGID属性。

k:判断目标文件是否存在,并且具有Sticky bit属性。

s:判断目标文件是否存在,并且是非空白文件。

三、字符串和数值测试

1、字符串测试

【字符串测试的操作符和命令】

字符串测试的操作符及其含义如下:

=:判断两个字符串是否相等,如果相等,则返回真(0).

!=:判断两个字符串是否不相等,如果不相等,则返回真。

z:测试字符串是否为空null(长度为0),为空则返回真。

n:测试字符串是否为非空,非空则返回真。

2、数值测试

【数值测试操作符】

eq:如果两个数相等,则返回真。

ne:如果两个数不相等,则返回真。

lt:如果第1个数小于第2个数,则返回真。

le:如果第1个数小于等于第2个数,则返回真。

gt:如果第1个数大于第2个数,则返回真。

ge:如果第1个数大于等于第2个数,则返回真。

使用上面的命令进行数值测试时,如果要判断两个数是否相等,也可以使用字符串测试中的“=”和“!=”进行测试。

四、逻辑操作符

【常用的逻辑操作符】

a:逻辑与,操作符两边都为真,结果为真,否则为假。

o:逻辑或,操作符两边至少有一个为真,结果为真,否则为假。

!:逻辑非。

五、捕获系统信号

在编写脚本时,可能会担心由于脚本的使用者发出来一个终止脚本运行的信号,Shell脚本就会终止运行,从而无法完成正在处理的工作。如果脚本正在处理一些无关紧要的工作,脚本终止可能不会有任何损失。但如果正在执行一项非常重要的工作,脚本终止就可能会带来损失。因此在重要的脚本中,应该捕获系统发出的终止信号并作出相应的动作,以免脚本终止带来不必要的损失。

【可以捕获的信号】

通常情况下,可以捕获的信号编号、名称及其含义如下:

1(SIGHUP):来自控制终端的挂起或来自控制进程的死亡信号。

2(SIGINT):来自键盘的中断信号。

3(SIGQUIT):来自键盘的退出信号。

15(SIGTERM):终止信号。

如果不确定脚本会捕获到那种信号,建议在重要的脚本中,捕获所有可以捕获的信号,以免带来不必要的损失。

【捕获信号后的措施】

在捕获到系统信号之后,脚本应该立即采取措施。通常可以采取以下3种措施:

不捕获信号,由系统处理这些信号。这会导致脚本结束执行、暂停等后果,这个办法通常用于不重要的脚本中。

捕获但忽略信号,即捕获到信号后部采取任何措施。

捕获信号并采取措施,这通常用于比较重要的脚本中。通常操作是提示用户是否需要中断脚本的执行,也可以向用户发出脚本正在执行不能退出的消息等。

【捕获信号的格式】

捕获系统信号使用命令trap,其基本格式如下:

trap “command” signals

在上面的格式中,command表示捕获到信号之后需要执行的命令或函数,如果为空(使用“”表示)则表示忽略信号,否则表示采取相应措施处理信号。signals表示要捕获的信号列表,可以使用数字表示,也可以使用信号名称表示。多个信号,空格分隔。

【用法示例】

在下面这个示例脚本中,将要捕获的是用户从键盘上发送的结束信号(案件为Ctrl+C,对应的信号为2),捕获到信号后脚本将调用函数trap,输出提示信息并退出:

!/bin/-- -n -n 

运行结果:

[root@localhost shell]# ./+->->->

按下快捷键Ctrl+C时,可以看到脚本捕获了用户从键盘发出的中断信号,并调用trap函数,显示提示信息并等待3秒后退出。

相关内容