shell脚本之二:条件测试语句和if流程控制语句的使用
1、read命令
1.1、内置变量read
除了“=”方式给变量赋值外,还可以使用bash的内置命令read来给变量赋值。
1.2、 定义
read命令用来提示用户从键盘读入数据,赋给变量。从而实现简单的交互过程。
1.3、 语法格式:
read [选项] [变量名1] [变量名1]……
-p:用来设置提示信息
-t:设置等待时间,单位是秒,若在规定时间内未输入自动跳出。
执行时将从标准输入设备(键盘)读入一行内容,并以空格作为分隔符,将读入的各字段挨个赋值给指定的变量,多余的内容赋值给最后一个变量。若指定的变量只有一个,则将整行内容赋值给此变量。
范例1:脚本内容如下
[root@localhost ~]# cat read.sh
执行脚本
[root@localhost ~]# sh read.sh
范例2:
[root@localhost ~]# read -p "Input one number: " NUM
Input one number: 123456
[root@localhost ~]# echo $NUM
123456
[root@localhost ~]# read -t 10 -p "Input tow number: " NUM1 NUM2
Input tow number: 345 789
[root@localhost ~]# echo $NUM1
345
[root@localhost ~]# echo $NUM2
789
2、test测试命令
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
格式:test 测试条件 或 [ 测试条件 ]
注意事项:中括号两边要有空格
条件测试常见的几种语法形式:
test 表达式
[ 表达式 ]
注意事项,中括号两边要有空格
其中:test和[ ]是等价的
2.1、 整数值比较
整数值比较指的是根据给定的两个整数值,判断第一个数与第二个数的关系,如是否大于、等于、小于第二个数。整数值比较的常用操作选项如下:
范例1:
若判断当前已登录的用户数,当超过5个时输出“Too many”,可以执行一下操作
范例2:
判断当前主机可用内存大小,当低于1024时输出具体数值,可以执行一下操作。
注:centos7系统开始,free命令显示结果中增加了available输出,表示估计有多少内存可用于启动新程序,即系统可用内存
2.2、 文件比较
范例1:
[root@localhost ~]# ll
total 8
-rw-r--r--. 1 root root 74 Jan 21 21:18 read-2.sh
-rw-r--r--. 1 root root 245 Jan 21 21:14 read.sh
[root@localhost ~]# test -f read.sh && echo true || echo false
true
[root@localhost ~]# test -f /read1.sh && echo true || echo false
false
[root@localhost ~]# test -d /mnt && echo true || echo false
true
[root@localhost ~]# test -f /mnt && echo true || echo false
false
[root@localhost ~]# test -d read.sh && echo true || echo false
false
[root@localhost ~]# [ -d /mnt ] && echo true || echo false
True
[root@localhost ~]# [ -d /backup ]
[root@localhost ~]# echo $? //通过$?变量的值可以判断前一步的条件测试结果。
1
[root@localhost ~]# [ ! -f xxx ] && echo true || echo false
true
[root@localhost ~]# [ ! -f read.sh ] && echo true || echo false
false
[root@localhost ~]# [ -x /root/read.sh ] && /root/read.sh
注意:
!表示取反的意思,即否定,感叹号和参数中间是有空格的
[ file1 -nt file2 ]:判断file1文件是否比file2文件新
[ file1 -ot file2 ]:判断file1文件是否比file2文件旧
[ file1 -ef file2 ]:判断两个文件是否为同一个文件,用来判断两个文件是否指向同一inode.
2.3、 字符串比较
操作符 |
说明 |
示例 |
== |
判断两个字符串是否相等 |
[ “$a” == “$b” ] |
!= |
判断两个字符串是否不相等 |
[ “$a” != “$b” ] |
-z 字符串 |
判断字符串是否为空 |
[ -z “$a” ] |
-n 字符串 |
判断字符串是否不为空 |
[ -n “$a” ] |
str1 > str2 |
判断字符串str1是否大于str2 |
[ “str1” \> “str2” ] |
str1 < str2 |
判断字符串str1是否小于str2 |
[ “str1” \< “str2” ] |
注意:对于进行字符串的测试,一定要将字符串加上双引号然后再进行比较,一定要注意空格,一般用在[ ]里面
范例1:
[root@localhost ~]# [ -n "abc" ] && echo 1 || echo 0
1
[root@localhost ~]# [ -n " " ] && echo 1 || echo 0
1
[root@localhost ~]# [ -n "" ] && echo 1 || echo 0
0
[root@localhost ~]# test -n "abc" && echo 1 || echo 0
1
[root@localhost ~]# [ -z "abc" ] && echo 1 || echo 0
0
[root@localhost ~]# [ -z "" ] && echo 1 || echo 0
1
2.4、 逻辑操作符
注:[[ ]]是扩展test命令,&& 、|| 、> 、<像这样符号可以用在[[ ]]中,不能用在[ ]中。
范例:
[root@localhost ~]# ll
total 8
-rw-r--r--. 1 root root 74 Jan 21 21:18 read-2.sh
-rw-r--r--. 1 root root 6 Jun 21 13:19 test
-rwxr-xr-x. 1 root root 245 Jan 21 21:14 read.sh
[root@localhost ~]# [ -f test -a -x read.sh ] && echo 1 || echo 0
1
[root@localhost ~]# [ -x test -a -x read.sh ] && echo 1 || echo 0
0
[root@localhost ~]# [ -x test -o -x read.sh ] && echo 1 || echo 0
1
[root@localhost ~]# [ -f test && -x read.sh ] && echo 1 || echo 0
-bash: [: missing `]'
0
[root@localhost ~]# [[ -f test && -x read.sh ]] && echo 1 || echo 0
1
[root@localhost ~]# [ -f test ] && [ -x read.sh ] && echo 1 || echo 0
1
[root@localhost ~]# [ -f test ] || [ -x read.sh ] && echo 1 || echo 0
1
3、流程控制语句if
在shell脚本应用中,if语句是最为常用的一种流程控制方式,用来根据特定的条件测试结果,分别执行不同的操作,根据不同的复杂程度,if语句的选择结构可以分为三种基本类型,使用于不同的应用场合。
3.2、 单分支
If语句的“分支”指的是不同测试结果所对应的执行语句(一条或多条)。对于单分支的选择结构,只有在“条件成立”时才会执行相应的代码,否则不执行任何操作。单分支if语句的执行流程和语法格式如下:
单分支 if 条件语句最为简单,如果符合条件则执行某个程序,否则什么事情都不做。语法如下:
if [ 条件判断 ] //方括号和条件判断之间至少一个空格
then
commands
fi
或
if [ 条件判断 ] ; then
commands
fi
在使用单分支 if 条件查询时需要注意几点:
if 语句使用 fi 结尾。
[ 条件判断 ] 就是使用 test 命令判断,所以中括号和条件判断之间必须有空格。
then 后面跟符合条件之后执行的程序,可以放在 [] 之后,用";"分隔;也可以换行写入,就不需要";"了。
范例1:判断某一目录是否存在,若不存在则新建此目录
[root@localhost ~]# cat chkdir.sh
执行脚本
[root@localhost ~]# sh chkdir.sh
/backup is not exist,will create it.
范例2:通过脚本判断根分区的使用率是否超过 80%,如果超过 80% 则向管理员报警,请他注意。 脚本就可以这样写:
说明:
其实这个脚本最主要的地方是
"rate=$(df -h|grep "/$" | awk '{print $5}' | cut -d"%" -f1)"这条命令,我们来分析一下这条命令:先使用"df -h"列出系统中的文件系统挂载情况;然后使用"grep"命令提取出根分区行;再使用"awk"命令列出第五列,也就是根分区使用率这一列(不过使用率是 20%,不好比较,还要提取出 20 这个数字);最后使用"cut"命令(cut 命令比 awk 命令简单),以"%"作为分隔符,提取出第一列。
cut是一个选取命令,就是将一段数据经过分析,取出我们想要的。-d指定分 隔符,这里以%为分隔符,-f指定哪个区域。
3.3、 双分支
在双分支 if 条件语句中,当条件判断式成立时,则执行某个程序;当条件判断式不成立时,则执行另一个程序。
格式:
if [ 条件判断 ]
then
commands
else
commands
fi
范例3:编写SHELL脚本(mkbak.sh)提示用户指定备份目录的路径,若目录已存则显示提示信息后跳过,否则显示相应信息后创建该目录。
脚本内容如下:
范例4:编写一个脚本,判断指定的某个用户是否存在,若存在则显示提示信息并跳过,否则就创建。
脚本内容如下:
说明:\<和\>,匹配词(word)的开始(\<)和结束(\>)。例如正则表达式\<the\>能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。
范例5:编写脚本程序(chkdbsvr.sh)用于每隔5分监视一次系统服务mysqld的运行状态,若发现mysqld进程已经停止,则在/var/log/mysql.log文件中追加写入日志信息(包括当时时间),并启动mysqld服务;否则不进行任何操作。
3.4、 多分支
在多分支 if 条件语句中,允许执行多次判断。也就是当条件判断 1 成立时,执行程序 1;当条件判断 2 成立时,执行程序 2;依次类推,当所有条件不成立时,执行最后的程序。语法如下:
格式:
If [ 条件判断1 ] ; then
commands
elif [ 条件判断2 ] ; then
commands
elif [ 条件判断3 ] ; then
commands
.......
else
commands
Fi
范例6:用多分支 if 条件语句来判断用户输入的是一个文件还是一个目录。
范例7:编写一个成绩分档的脚本grade.sh,根据输入的考试分数不同来区分优秀、合格、不合格三挡。