条件测试
条件测试基本语法
在 s h e l l shell shell程序中,用户可以使用测试语句来测试指定的条件表达式的条件的真或者假。当指定的条件为真时,整个条件测试的返回值为0;反之,如果指定的条件为假,则条件测试语句的返回值为非0值。
这一点与其他程序设计语言不一样,是为了保持与 s h e l l shell shell程序的退出状态一致。当某个 s h e l l shell shell程序成功执行后,该进程会返回一个0值;而如果该程序执行错误,则会返回一个非0值
条件测试的语法有两种,分别是 t e s t test test和 [ [ [命令,下面分别来讲解它们的语法
1) t e s t test test
在绝大多数的 s h e l l shell shell中, t e s t test test都是作为一个内部命令出现的,当然,在某些 s h e l l shell shell中,同时也提供了一个相同名称的外部命令。但是,在使用 t e s t test test命令进行条件测试时,如果没有指定绝对路径,则使用的都是内部命令。 t e s t test test语法如下:
test expression
其中,参数 e x p r e s s i o n expression expression表示需要测试的条件表达式,可以由字符串、整数、文件名,以及各种运算符组成。下面给出几个有效的条件表达式:
1 -eq 2 #测试两个整数是否相等
'string' #测试字符串是否为空
-z 'string'
-e file #测试指定文件是否存在
2) [ [ [
与 t e s t test test命令相同, [ [ [命令的作用也是对后面的条件表达式进行测试,但是为了增加程序的可读性, s h e l l shell shell要求在表达式后面追加一个右方括号 ] ] ]来与前面的 [ [ [命令配对。语法如下:
[ expression ]
[ [ [是命令, e x p r e s s i o n expression expression是条件表达式。条件表达式和左右方括号之间都必须有一个空格
左方括号 [ [ [是一个 s h e l l shell shell命令,而非条件表达式的一部分。而命令与参数之间必须保留一个空格。所以,在上面的语法中, e x p r e s s i o n expression expression与左右括号都需保留一个空格
字符串测试
在 s h e l l shell shell中,可以通过5种运算符来对字符串进行操作
字符串运算符
运算符 | 说明 |
---|---|
s t r i n g string string | 判断指定的字符串是否为空 |
s t r i n g 1 string1 string1 = t r i n g 2 tring2 tring2 | 判断两个字符串是否相等 |
s t r i n g 1 string1 string1 != s t r i n g 2 string2 string2 | 判断两个字符串是否不相等 |
− n -n −n s t r i n g string string | 判断 s t r i n g string string是否是非空串 |
− z -z −z s t r i n g string string | 判断 s t r i n g string string是否是空串 |
例1:字符串测试
root@VM-0-2-ubuntu:/home/ubuntu# a="abc"
root@VM-0-2-ubuntu:/home/ubuntu# test $a #测试是否为空
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0 #不为空
root@VM-0-2-ubuntu:/home/ubuntu# test -n "$a" #测试是否是非空串
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0 #是非空串
root@VM-0-2-ubuntu:/home/ubuntu# test -z "$a" #测试是否是空串
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1 #不是空串
root@VM-0-2-ubuntu:/home/ubuntu# a="hello"
root@VM-0-2-ubuntu:/home/ubuntu# b="world"
root@VM-0-2-ubuntu:/home/ubuntu# [ "$a" = "$b" ] #测试两个字符串是否相等
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
root@VM-0-2-ubuntu:/home/ubuntu# test "$a" != "$b" #测试两个字符串是否不相等
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# test "$a"="$b" #测试两个字符串是否相等
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0 #这里本来不相等,但却返回了0?是因为测试运算符=左右两边没有空格,导致测试错误
root@VM-0-2-ubuntu:/home/ubuntu# test "$a" = "$b"
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
通过上面的测试,对于字符串测试应该基本了解,但应注意以下两点:
- 在给变量赋值的时候,等号"="左右两边一定不要有空格;否则, s h e l l shell shell会把空格前面的字符串当作 s h e l l shell shell命令
- 在测试运算符"="、"!="、及"-z"等符号的左右两边,一定含有空格
整数测试
与字符串测试类似,整数测试也有以下两种形式的语法:
test number1 op number2
或者
[ number1 op number2 ]
用户可以利用 s h e l l shell shell提供的整数运算符来进行两个整数的比较。
常见整数运算符
运算符 | 说明 |
---|---|
n u m b e r 1 number1 number1 − e q -eq −eq n u m b e r 2 number2 number2 | 比较 n u m b e r 1 number1 number1和 n u m b e r 2 number2 number2是否相等。如果相等,测试结果为0 |
n u m b e r 1 number1 number1 − n e -ne −ne n u m b e r 2 number2 number2 | 比较 n u m b e r 1 number1 number1和 n u m b e r 2 number2 number2是否不相等。如果不相等,测试结果为0 |
n u m b e r 1 number1 number1 − g t -gt −gt n u m b e r 2 number2 number2 | 比较 n u m b e r 1 number1 number1是否大于 n u m b e r 2 number2 number2。如果大于,测试结果为0 |
n u m b e r 1 number1 number1 − l t -lt −lt n u m b e r 2 number2 number2 | 比较 n u m b e r 1 number1 number1是否小于 n u m b e r 2 number2 number2。如果小于,测试结果为0 |
n u m b e r 1 number1 number1 − g e -ge −ge n u m b e r 2 number2 number2 | 比较 n u m b e r 1 number1 number1是否大于等于 n u m b e r 2 number2 number2。如果大于等于,测试结果为0 |
n u m b e r 1 number1 number1 − l e -le −le n u m b e r 2 number2 number2 | 比较 n u m b e r 1 number1 number1是否小于等于 n u m b e r 2 number2 number2。如果小于等于,测试结果为0 |
例2:整数测试
root@VM-0-2-ubuntu:/home/ubuntu# [ 12 -eq 14 ] #测试是否相等
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
root@VM-0-2-ubuntu:/home/ubuntu# test 12 -gt 14 #测试12是否大于14
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
root@VM-0-2-ubuntu:/home/ubuntu# test 12 -lt 14 #测试12是否小于14
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# x=365
root@VM-0-2-ubuntu:/home/ubuntu# test "$x" -eq 365 #测试变量与常数的大小
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# test "$x" -gt 364
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# x=133
root@VM-0-2-ubuntu:/home/ubuntu# y=36
root@VM-0-2-ubuntu:/home/ubuntu# [ "$x" -le "$y" ] #测试两个变量的大小
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
root@VM-0-2-ubuntu:/home/ubuntu# [ 12 = 13 ] #使用等号比较则将其当作字符串进行比较
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
root@VM-0-2-ubuntu:/home/ubuntu# [ 12 -eq 13 ]
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
#上述表列出的运算符仅仅针对整数,使用了非整数便会报错
root@VM-0-2-ubuntu:/home/ubuntu# x=12.3
root@VM-0-2-ubuntu:/home/ubuntu# y=12
root@VM-0-2-ubuntu:/home/ubuntu# [ "$x" -gt "$y" ]
bash: [: 12.3: integer expression expected
字符串运算符和整数运算符不可以混用
文件测试
文件测试的语法如下:
test op file
或者
[ op file ]
上述语法中 o p op op表示操作符
常用文件操作符
操作符 | 说明 |
---|---|
− a -a −a f i l e file file | 文件是否存在。如果 f i l e file file存在,则结果为0 |
− b -b −b f i l e file file | 文件是否存在,且为块文件。如果 f i l e file file是一个已经存在的块文件,则结果为0 |
− c -c −c f i l e file file | 文件是否存在,且为字符文件。如果 f i l e file file是一个已经存在的字符文件,则结果为0 |
− d -d −d f i l e file file | 文件是否存在,且为目录。如果 f i l e file file是一个已经存在的目录,则结果为0 |
− e -e −e f i l e file file | 同- a a a操作符 |
− s -s −s f i l e file file | 文件的长度是否大于0或者文件为非空文件。如果 f i l e file file是一个非空文件,则结果为0 |
− f -f −f f i l e file file | 文件存在,且为常规文件。如果 f i l e file file是一个已经存在的常规文件,则结果为0 |
− w -w −w f i l e file file | 文件是否存在且可写。如果文件按是一个可写文件则结果为0 |
− L -L −L f i l e file file | 文件是否存在,且为符号链接。如果 f i l e file file是一个已经存在的符号链接,则结果为0 |
− u -u −u f i l e file file | 文件是否设置 s u i d suid suid位。如果 f i l e file file已经设置了 s u i d suid suid位,则结果为0 |
− r -r −r f i l e file file | 文件是否存在且可读。如果文件按是一个可读文件则结果为0 |
− x -x −x f i l e file file | 文件是否存在且可执行。如果文件按是一个可执行文件则结果为0 |
例3:文件测试
root@VM-0-2-ubuntu:/home/ubuntu# ll
total 112
drwxr-xr-x 17 ubuntu ubuntu 4096 Mar 5 23:08 ./
drwxr-xr-x 3 root root 4096 Aug 8 2018 ../
-rw------- 1 ubuntu ubuntu 4520 Mar 10 14:57 .bash_history
-rw-r--r-- 1 ubuntu ubuntu 220 Aug 8 2018 .bash_logout
-rw-r--r-- 1 ubuntu ubuntu 3773 Sep 11 16:32 .bashrc
drwxr-xr-x 14 root root 4096 Dec 29 20:55 C++/
drwx------ 2 ubuntu ubuntu 4096 Aug 9 2018 .cache/
drwxr-xr-x 2 root root 4096 Feb 22 21:48 chat/
root@VM-0-2-ubuntu:/home/ubuntu# test -a chat #测试文件是否存在
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# [ -a file ] #给一个不存在的文件名判断是否存在
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
root@VM-0-2-ubuntu:/home/ubuntu# test -d chat #判断chat是否为目录
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# test -f chat #判断是否为常规文件
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
root@VM-0-2-ubuntu:/home/ubuntu# test -s chat #判断chat是否为非空文件
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# test -b chat #判断chat是否为块文件
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
1
root@VM-0-2-ubuntu:/home/ubuntu# test -c /dev/tty #判断/dev/tty是否为字符文件
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# test -w chat #判断chat是否可读
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# test -r chat #判断chat是否可写
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# test -x chat #判断chat是否可执行
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
逻辑操作符
s h e l l shell shell中的逻辑操作符可以将多个不同的条件组合起来,从而构成一个复杂的条件表达式
常用的逻辑操作符
操作符 | 说明 |
---|---|
! e x p r e s s i o n !expression !expression | 逻辑非,条件表达式 e x p r e s s i o n expression expression的值为假,则该操作符的运算结果为真 |
e x p r e s s i o n 1 expression1 expression1 − a -a −a e x p r e s s i o n 2 expression2 expression2 | 逻辑与,条件表达式 e x p r e s s i o n 1 expression1 expression1和 e x p r e s s i o n 2 expression2 expression2的值都是真时,整个表达式的值才为真 |
e x p r e s s i o n 1 expression1 expression1 − o -o −o e x p r e s s i o n 2 expression2 expression2 | 逻辑或,条件表达式 e x p r e s s i o n 1 expression1 expression1或者 e x p r e s s i o n 2 expression2 expression2的值有一个为真时,整个表达式的值就为真 |
例4:逻辑操作符测试
root@VM-0-2-ubuntu:/home/ubuntu# a=35
root@VM-0-2-ubuntu:/home/ubuntu# test "$a" -gt 20 -a "$a" -lt 60 #判断变量a的值是否大于20小于60
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
root@VM-0-2-ubuntu:/home/ubuntu# [ -e chat -a -w chat ] #判断当前用户是否拥有某个文件的写入权限
root@VM-0-2-ubuntu:/home/ubuntu# echo $?
0
条件判断语句
1.使用简单的if语句进行判断
基本格式:
if ecpression
then
statment1
statment2
..
fi
例4:通过条件测试判断某些文件的类型
#! /bin/bash
#通过条件测试判断/bin/bash是否为一个常规文件
if [ -f /bin/bash ]
then echo "/bin/bash is a file"
fi
执行结果:
例5:使用空命令作为判断条件
#! /bin/bash
if :; echo "always true"; fi
空命令":"的退出状态永远为0,因此会输出 a l w a y s always always t r u e true true
例6:使用&&代替 i f if if语句进行判断
#! /bi/bash
test "$whoami" != "root" && (echo you are using a non-privileged account; exit 1)
该判断语句首先对当前用户进行判断,如果当前用户不为 r o o t root root,也即为真则输出后面的说明语句
2.使用if else 语句进行流程控制
if expression
then
statement1
statement2
..
else
statement3
statement4
..
fi
3.使用if elif进行多条件判断
if expression
then
statement1
statement2
..
elif expression
then
statement3
statement4
..
else
statement5
..
fi
4.使用exit语句退出程序
基本语法:
exit status
s t a t u s status status参数表示退出状态,该参数是一个整数值,其取值范围为0~255;按照惯例,退出状态0意味着脚本成功运行完毕;而非0通常意味着程序执行过程中出现某些错误,因此,用户可以用其它的非0值来给父进程传递不同的消息,根据子进程的成功或者失败,父进程采取不同的措施,如果没有参数给 e x i t exit exit语句,那么由 e x i t exit exit语句之前的那条语句的执行状态来决定。
例7:演示在不同情况下,程序返回不同的状态码
#! /bin/bash
echo hellp world!
#使用$?变量获取echo语句的执行状态
echo $?
#执行一个无效的命令
aaa
#输出执行状态
echo $?
#退出
exit 120
执行结果:
由于输入了一个无效命令,所以执行该无效命令后的执行状态为127;接着手动获取程序执行后的执行状态:
正是我们在程序末尾使用
e
x
i
t
exit
exit的返回值
通常每个状态码都有其特定涵义,因此在返回这些状态码时要注意,避免执行脚本时产生误解
5.多条件判断语句case
c a s e case case语句基本语法:
case variable in
value1)
statement1
statement2
..
statementn;;
value2)
statement1
statement2
..
statementn;;
...
valuen)
statement1
statement2
..
statementn;;
#其它情况
*)
statement1
statement2
..
statementn;;
#相当于if 结尾fi
esac
6.利用case语句处理用户输入
例8:说明case语句的使用方法
#! /bin/bash
echo "Hit a key, then hit return."
#读取用户按下的键
read keypress
#case语句开始
case "$keypress" in
#小写字母
[ [:lower:] ])
echo "Lowercase letter.";;
[ [:upper:] ])
echo "Uppercase letter.";;
[0-9])
echo "Digit.";;
*)
echo "other letter.";;
esac
执行结果:
7.运算符
1.使用
e
x
p
r
expr
expr外部程序
基本语法:
expr expression
例9:演示使用 e x p r expr expr命令计算不同的算法运算
#! /bin/bash
#注意:要用反引号括起来
result=`expr 2 - 100`
echo "$result"
result=`expr 2 + 100`
echo "$result"
result=`expr 2 \* 5`
echo "$result"
result=`expr 24 / 8`
echo "$result"
result=`expr \(2 - 6 \) \* 12`
echo "$result"
#错误的语法
result=`expr 2+5`
echo "$result"
result=`expr 2-4*9`
echo "$result"
result=`expr 1-(4-7)`
echo "$result"
执行结果:
使用expr命令时要注意运算符左右两边的空格,同时需要将括号进行转义表示
2.使用$((…))
例10:演示使用$((…))符号进行算术运算
#! /bin/bash
result=$((3+6))
echo "$result"
result=$(( 3 * 6 ))
echo "$result"
result=$(( 7 / 5 ))
echo "$result"
result=$(( 8 % 3 ))
echo "$result"
result=$(( (1-4) * 5 ))
echo "$result"
执行结果:
3.使用 l e t let let命令
例11:演示使用 l e t let let命令执行算术运算
#! /bin/bash
n=10
let n=n+1
echo "$n"
let n=n*10
echo "$n"
let n=n**2
echo "$n"
执行结果:
4.使用位运算符
例12:演示使用位运算符的方法
#! /bin/bash
result=$[ 2 << 3 ]
echo "$result"
result=$[ 8>> 2 ]
echo "$result"
result=$[ 8 & 4 ]
echo "$result"
result=$[ ~8 ]
echo "$result"
result=$[ 10 ^ 6 ]
echo "$result"
执行结果: