条件测试
为了能够正确处理Shell程序运行过程中遇到的各种情况,Linux Shell提供了一组测试运算符。通过这些运算符,Shell程序能够判断某种或者几个条件是否成立。条件测试在各种流程控制语句,例如判断语句和循环语句中发挥了重要的作用,所以,了解和掌握这些条件测试是非常重要的。
基本语法
在Shell程序中,用户可以使用测试语句来测试指定的条件表达式的条件的真或者假。当指定的条件为真时,整个条件测试的返回值为0;反之,如果指定的条件为假,则条件测试语句的返回值为非0值。
条件测试的语法有2种,分别是test命令和[命令,test命令的语法如下:
test expression
其中,参数expression表示需要进行测试的条件表达式,可以由字符串、整数、文件名以及各种运算符组成。例如,下面的表达式都是有效的条件表达式:
1 -eq 2 //判断1是否等于2
‘string’ //永真
-z ‘string’
-e file //判断文件是否为空
[命令的语法如下:
[ expression ]
在上面的语法中,[是条件测试命令,参数expression是一个条件表达式。其中expression的语法与上面的test命令中的语法完全相同。条件表达式和左右方括号之间都必须有一个空格。
字符串测试
通常情况下,对于字符串的操作主要包括判断字符串变量是否为空以及两个字符串是否相等。在Shell中,用户可以通过5种运算符来对字符串进行操作。
运算符 | 说明 |
---|---|
string | 判断指定字符串是否为空 |
string1=string2 | 判断2个字符串string1和string2是否相等 |
strig1!=string2 | 判断2个字符串string1和string2是否不相等 |
-n string | 判断string是否是非空串 |
-z string | 判断string是否是空串 |
【例4-1】演示字符串测试的使用方法
#定义字符串变量
[root@localhost chapter4]# a="abc"
#使用test命令测试变量$a是否为空串
[root@localhost chapter4]# test $a
#通过echo命令和$?环境变量输出测试结果
[root@localhost chapter4]# echo $?
#输出结果为0,表示变量$a的值不为空
0
#使用-n运算符测试变量$a是否不为空
[root@localhost chapter4]# test -n "$a"
#输出测试结果
[root@localhost chapter4]# echo $?
#测试结果为0表示变量为非空字符串
0
#使用-z运算符测试变量$a是否为空串
[root@localhost chapter4]# test -z "$a"
#测试结果为1,表示变量$a不是空串
[root@localhost chapter4]# echo $?
1
【例4-2】演示Shell中比较2个字符串值的方法
#定义变量$a
[root@localhost chapter4]# a="hello"
#定义变量$b
[root@localhost chapter4]# b="world"
#比较2个字符串是否相等
[root@localhost chapter4]# [ "$a" = "$b" ]
#输出测试结果为1,表示$a和$b不相等
[root@localhost chapter4]# echo $?
1
#测试$a和$b是否不相等
[root@localhost chapter4]# test "$a" != "$b"
#输出测试结果为0,表示$a和$b不相等
[root@localhost chapter4]# echo $?
0
【例4-3】说明空格对于字符串比较结果的影响
#定义字符串变量$a
[root@localhost chapter4]# a="Hello world. "
#定义字符串变量$b
[root@localhost chapter4]# b="Hello world."
#测试$a和$b是否相等
[root@localhost chapter4]# [ "$a" = "$b" ]
[root@localhost chapter4]# echo $?
1
【例4-4】演示字母大小写对于字符串比较结果的影响
#变量$a的第1个字母为大写的H
[root@localhost chapter4]# a="Hello world."
#变量$b的第1个字母为小写的h
[root@localhost chapter4]# b="hello world."
[root@localhost chapter4]# [ "$a" = "$b" ]
#变量$a和$b的值不相等
[root@localhost chapter4]# echo $?
1
整数测试
与字符串测试类似,整数测试也有2种形式的语法:
test number1 op number2
或者
[ number1 op number2 ]
其中,number1和number2分别表示参与比较的2个整数,可以是常量或者变量。op表示运算符。
运算符 | 说明 |
---|---|
number1 -eq number2 | 比较number1是否等于number2。如果相等,测试结果为0 |
number1 -ne number2 | 比较number1和number2是否不相等。如果number1和number2不相等,测试结果为0 |
number1 -gt number2 | 比较number1是否大于number2。如果number1大于number2,测试结果为0 |
number1 -lt number2 | 比较number1是否小于number2。如果number1小于number2,测试结果为0 |
number1 -ge number2 | 试number1是否大于等于number2。如果number1大于等于number2,测试结果为0 |
number1 -le number2 | 试number1是否小于等于number2。如果number1小于等于number2,测试结果为0 |
【例4-5】比较2个整数是否相等
[root@localhost chapter4]# [ 12 -eq 14 ]
[root@localhost chapter4]# echo $?
1
【例4-6】比较2个整数的大小
[root@localhost chapter4]# test 12 -gt 14
[root@localhost chapter4]# echo $?
1
[root@localhost chapter4]# test 12 -lt 14
[root@localhost chapter4]# echo $?
0
【例4-7】比较变量与常数的大小
[root@localhost chapter4]# x=365
[root@localhost chapter4]# test "$x" -eq 365
[root@localhost chapter4]# echo $?
0
[root@localhost chapter4]# test "$x" -gt 364
[root@localhost chapter4]# echo $?
0
【例4-8】比较2个变量值的大小。在本例中,首先定义2个整数变量$x和$y,然后判断变量$x是否小于或者等于变量$y。
[root@localhost chapter4]# x=123
[root@localhost chapter4]# y=36
[root@localhost chapter4]# [ "$x" -le "$y" ]
[root@localhost chapter4]# echo $?
1
【例4-9】使用=比较两个整数会导致错误结果。
[root@localhost chapter4]# [ 12 = 13 ]
[root@localhost chapter4]# echo $?
1
[root@localhost chapter4]# [ 12 -eq 13 ]
[root@localhost chapter4]# echo $?
1
【例4-10】使用针对整数的运算符来比较非整数会导致错误结果。
[root@localhost chapter4]# x=12.3
[root@localhost chapter4]# y=12
[root@localhost chapter4]# [ "$x" -gt "$y" ]
-bash: [: 12.3: integer expression expected
文件测试
文件测试的语法如下:
test op file
或者
[ op file ]
在上面的语法中,op表示操作符,常用的操作符参见表4.3,其中file表示要测试的文件名。
【例4-11】通过文件操作符来判断文件是否存在
[root@localhost chapter4]# test -a file1
[root@localhost chapter4]# echo $?
0
【例4-12】判断文件是否存在。
[root@localhost chapter4]# [ -a file3 ]
[root@localhost chapter4]# echo $?
1
【例4-13】通过操作符判断各种文件类型
[root@localhost chapter4]# test -d dir1
[root@localhost chapter4]# echo $?
0
[root@localhost chapter4]# test -f file1
[root@localhost chapter4]# echo $?
08 0
[root@localhost chapter4]# test -s file2
[root@localhost chapter4]# echo $?
1
[root@localhost chapter4]# test -b file1
[root@localhost chapter4]# echo $?
1
[root@localhost chapter4]# test -b /dev/sda
[root@localhost chapter4]# echo $?
0
[root@localhost chapter4]# test -c /dev/tty
[root@localhost chapter4]# echo $?
0
【例4-14】通过文件测试判断用户对文件的访问权限
[root@localhost chapter4]# test -w file1
[root@localhost chapter4]# echo $?
0
[root@localhost chapter4]# test -r file1
[root@localhost chapter4]# echo $?
0
[root@localhost chapter4]# test -x file1
[root@localhost chapter4]# echo $?
1
[root@localhost chapter4]# test -x hello.sh
[root@localhost chapter4]# echo $?
0
【例4-15】使用chmod命令为hello.sh文件设置setuid权限,这样的话执行该文件的用户就会临时用户该文件所有者的权限
[root@localhost chapter4]# chmod u+s hello.sh
[root@localhost chapter4]# ll
total 12
drwxr-xr-x 2 root root 4096 Nov 9 14:50 dir1
-rw-r--r-- root root 12 Nov 9 14:49 file1
-rw-r--r-- 1 root root 0 Nov 9 14:49 file2
-rwsr-xr-x 1 root root 30 Nov 9 15:06 hello.sh
[root@localhost chapter4]# test -u hello.sh
[root@localhost chapter4]# echo $?
0
逻辑操作符
Shell中的逻辑操作符可以将多个不同的条件组合起来,从而构成一个复杂的条件表达式。
【例4-16】判断整数变量$a的值是否大于20,并且小于60。
[root@localhost chapter4]# a=35
[root@localhost chapter4]# test "$a" -gt 20 -a "$a" -lt 60 //a既大于20且a小于60
[root@localhost chapter4]# echo $?
0
【例4-17】通过条件测试来判断当前用户是否拥有某个文件的写入权限
[root@localhost chapter4]# [ -e file1 -a -w file1 ]
[root@localhost chapter4]# echo $?
0
条件判断语句
条件判断语句是一种最简单的流程控制语句。该语句使得程序根据不同的条件来执行不同的程序分支。本节将介绍Shell程序设计中的简单的条件判断语句。
使用简单的if语句进行条件判断
条件判断语句使用if语句来实现。最简单的if语句的语法如下:
if expression
then
statement1
statement2
...
fi
在上面的语法中,expression通常代表一个条件表达式,但是也可以是Shell命令。
为了使得代码更加紧凑,在某些情况下,我们可以将if子句和then子句写在同一行中。此时,需要在expression表达式后面加上一个分号,如下:
if expression; then
statement1
statement2
fi
分号的作用是表示if子句已经结束,后面的代码是then子句。
【例4-18】通过条件测试判断文件类型
#!/bin/bash
#使用条件测试判断/bin/bash是否是一个常规文件
if [ -f /bin/bash ]
then echo "/bin/bash is a file"
fi
运行以上程序
[root@localhost ~]# ./test.sh
/bin/bash is a file
【例4-19】通过条件测试判断文件是否创建成功
#!/bin/bash
#通过echo命令和重定向创建一个文件
echo "hello world!" > ./msg.log
if [ -f ./msg.log ]; then echo "file has been created."; fi
运行以上结果得:
[root@localhost ~]# ./test.sh
file has been created.
【例4-20】使用空命令作为判断条件
#!/bin/bash
#使用空命令作为条件
if :; then echo "always true"; fi
以上运行结果:
[root@localhost ~]# ./test.sh
always true
【例4-21】使用&&操作符代替if语句
#!/bin/bash
#使用&&操作符代替if语句
test "$(whoami)" != "root" && (echo you are using a non-privileged account; exit 1)
如果以root用户的身份执行【例4-21】,则没任何输出,如下:
[root@localhost chapter4]# ./test.sh
而当我们切换到其他用户再执行该程序时,则会输出有关提示信息,如下:
[root@localhost ~]# su - redhat
[redhat@localhost ~]$ ./test.sh
you are using a non-privileged account
if else语句的基本语法如下:
if expression
then
statement1
statement2
…
else
statement3
statement4
…
fi
在上面的语法中,expression表示if语句的执行条件,可以是条件表达式或者一个Shell命令。如果expression的值为真,则执行then子句中的语句statement1、statement2…。如果expression的值为假,则执行else子句中的语句,包括statement3、statement4、…,最后通过fi关键字结束整个if代码块。
【例4-22】使用if else语句进行流程控制
#!/bin/bash
#输出提示信息
echo "Please enter a number:"