条件测试
test命令可用于测试表达式是否成立,成立返回0值,不成立返回其他值
- test 条件表达式
- [ 条件表达式 ]
文件测试与整数测试
文件测试
- 使用test
- [ 操作符 文件或目录 ]
常用的测试操作符 - -d:测试是否为目录(Directory)
- -e:测试目录或文件是否存在(Exist)
- -f:测试是否文文件(File)
- -r:测试当前用户是否有权限读取(Read)
- -w:测试当前用户是否有权限写入(Write)
- -x:测试当前用户是否有权限执行
[root@localhost ~]# test -d /etc/ssh
[root@localhost ~]# echo $?
0 ##是目录,上条命令成立
[root@localhost ~]# test -f /etc/ssh
[root@localhost ~]# echo $?
1 ##不是文件,上条命令不成立
[root@localhost ~]# [-d /etc/ssh] ##因为前后缺少空格,所以报错
bash: [-d: 未找到命令
[root@localhost ~]# [ -d /etc/ssh ] ##
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ -r /etc/passwd ]
[root@localhost ~]# echo $?
0 ##当前root用户有读权限
[root@localhost ~]# [ -w /etc/passwd ]
[root@localhost ~]# echo $?
0 ##当前root有写权限
[root@localhost ~]# [ -x /etc/passwd ]
[root@localhost ~]# echo $?
1 ##当前root用户没有执行权限
[root@localhost ~]# ls -lh /etc/passwd
-rw-r--r--. 1 root root 917 7月 15 22:35 /etc/passwd
[root@localhost ~]#
[root@localhost ~]# [ -f /etc/passwd ]&& echo "yes" ##“&&”前面的条件成立则输出yes
yes
[root@localhost ~]# [ -d /etc/passwd ]&& echo "yes"
[root@localhost ~]#
整数值比较
- [ 整数1 操作符 整数2 ]
常用的测试操作符 - -eq:等于(Equal)
- -ne:不等于 (Not Equal)
- -lt:小于(Lesser Than)
- -gt:大于(Greater Than)
- -le:小于或等于(Lesser or Equal)
- -ge:大于或等于(Greater or Equal)
[root@localhost ~]# [ 5 -gt 4 ]&& echo "yes"
yes
[root@localhost ~]# [ 80 = 80 ]&& echo "yes"
yes
[root@localhost ~]# [ 80 == 80 ]&& echo "yes" ##这个和下面的 -eq是一样的
yes
[root@localhost ~]# [ 80 -eq 80 ]&& echo "yes"
yes
[root@localhost ~]#
[root@localhost ~]# [ $(who |wc -l) -lt 5 ]&& echo "Usernumber formal" ##$()是执行()内的指令,计算当前登录的用户,与5比较,若小于5则输出后面的语句
Usernumber formal
[root@localhost ~]#
[root@localhost ~]# free -m ##查看内存使用情况,free表示空闲的
total used free shared buff/cache available
Mem: 3770 769 2282 24 718 2756
Swap: 3967 0 3967
[root@localhost ~]# MEMBER=`free -m |grep "Mem:" |awk '{print $4}'`
[root@localhost ~]# echo $MEMBER
2283
[root@localhost ~]# MEMBER=$(free -m |grep "Mem:" |awk '{print $4}')
[root@localhost ~]# [ $MEMBER -gt 2000 ]&& echo "$MEMBER"MB
2282MB
[root@localhost ~]# [ $MEMBER -gt 2000 ]&& echo "${MEMBER}MB"
2282MB
[root@localhost ~]# [ $MEMBER -gt 2000 ]&& echo "$MEMBER MB"
2282 MB
[root@localhost ~]#
-eq、-le、-ge等以上操作符仅用于数值比较
字符串测试与逻辑测试
字符串测试
常用的格式
格式一:[ 字符串1 = 字符串2 ]
[ 字符串1 != 字符串2 ]
格式二:[ -z 字符串 ]
常用的测试操作符
- =:第一个字符串与第二个字符串内容相同
- !=:第一个字符串与第二个字符串内容不同,!号表示相反的意思
- -z:检查字符串内容是否为空,对于未定义或赋予空值的变量将视为空串
[root@localhost ~]# [ 'zhang' = 'zhang' ]&& echo "yes"
yes
[root@localhost ~]# [ 'zhang' = 'zhan' ]&&echo "yes"
[root@localhost ~]# [ ! 'zhang' = 'zhan' ]&&echo "yes" ##'zhang' = 'zhan'不成立,!取反后成立
yes
[root@localhost ~]# [ -z "" ]&& echo "yes" ##检查空
yes
[root@localhost ~]# [ -z " " ]&& echo "yes" ##空格也算字符
[root@localhost ~]# [ -z "$MEMBER" ]&& echo "yes" ##之前定义过的变量,并附了值,不为空
[root@localhost ~]# [ -z "$ABC" ]&& echo "yes" ##未定义的变量
yes
[root@localhost ~]#
逻辑测试
基本格式
- 格式一: [ 表达式1 ] 操作符 [ 表达式2 ] …
格式二: 命令1 操作符 命令2 …
常用测试操作符 - &&:逻辑与,“而且”的意思,使用test命令测试时,可将“&&”改为“-a”
- ||:逻辑或,“或者”的意思,使用test命令测试时,可将“||”改为“-o”
- !:逻辑否
[root@localhost ~]# [ -d /etc ] && [ -r /etc ] && echo "you can open it"
you can open it
[root@localhost ~]#
if语句
if单分支语句
单分支结构(基本格式)
- if 条件测试操作
then 命令序列
fi
单分支结构(举例)
- if 磁盘已用空间>80%
then 报警
fi
逻辑结构图
[root@localhost ~]# vim f.sh
#!/bin/bash
#
read -p "请输入一个路径:" K
if [ !-d $k ]
then
mkdir -p $K
echo "你输入的路径不是一个目录,为你创建目录:$K"
fi
[root@localhost ~]# ./f.sh
请输入一个路径:/opt/opt10
你输入的路径不是一个目录,为你创建目录:/opt/opt10
[root@localhost ~]# cd /opt
[root@localhost opt]# ls
opt08 opt10 rh
if双分支语句
双分支结构(基本格式)
- if 条件测试操作
then 命令序列1
else
命令序列2
fi
双分支结构(举例)
- if 80端口是否在监听
then 网站服务已在运行
else
启动httpd服务
fi
[root@localhost opt]# ls
opt08 opt10 opt11 opt12 rh test10
[root@localhost opt]# cd
[root@localhost ~]# vi f.sh
#!/bin/bash
#
read -p "请输入一个路径:" K
if [ -d $K ]
then
echo "路径目录已存在"
else
mkdir -p $K
echo "你输入的路径不是一个目录,为你创建目录:$K"
fi
[root@localhost ~]# ./f.sh
请输入一个路径:/opt/opt08
路径目录已存在
[root@localhost ~]# ./f.sh
请输入一个路径:/opt/opt15
你输入的路径不是一个目录,为你创建目录:/opt/opt15
[root@localhost ~]#
if多分支语句
多分支结构(基本格式)
- if 条件测试操作1
then 命令序列1
elif 条件测试操作2
then 命令序列2
else 命令序列3
fi
多分支结构(举例)
- if 分数为85~100之间
then 判为优秀
elif 分数为70~84之间
then 判为合格
else
判为不合格
fi
[root@localhost ~]# vim ifd.sh
#!/bin/bash
#
read -p "请输入成绩(0-100):" C
if [ $C -ge 85 ] && [ $C -le 100 ];then ##85到100为优秀
echo "成绩优秀"
elif [ $C -ge 70 ] && [ $C -le 84 ];then
echo "成绩良好"
elif [ $C -ge 60 ] && [ $C -le 69 ];then
echo "成绩合格"
elif [ $C -ge 0 ] && [ $C -le 59 ];then
echo "成绩不合格"
else
echo "请输入正确成绩范围(0-100)"
fi
[root@localhost ~]# chmod +x ifd.sh
[root@localhost ~]# ./ifd.sh
请输入成绩(0-100):59
成绩不合格
[root@localhost ~]# ./ifd.sh
请输入成绩(0-100):60
成绩合格
[root@localhost ~]# ./ifd.sh
请输入成绩(0-100):74
成绩良好
[root@localhost ~]# ./ifd.sh
请输入成绩(0-100):85
成绩优秀
[root@localhost ~]# ./ifd.sh
请输入成绩(0-100):101
请输入正确成绩范围(0-100)
[root@localhost ~]#
[root@localhost ~]# vi pinghost.sh
#!/bin/bash
#
ping -c 3 -i 0.2 -W 3 $1 ##-c表示发3个包,-i表示间隔0.2s发一次,-W表示超时3秒则失败,$1对应主机ip
if [ $? -eq 0 ];then ##$?表示上条命令的执行状态,会返回0和非0值
echo "Host $1 is up"
else
echo "Host $1 is down"
fi
[root@localhost ~]# ./pinghost.sh 20.0.0.130
PING 20.0.0.130 (20.0.0.130) 56(84) bytes of data.
64 bytes from 20.0.0.130: icmp_seq=1 ttl=64 time=0.482 ms
64 bytes from 20.0.0.130: icmp_seq=2 ttl=64 time=0.454 ms
64 bytes from 20.0.0.130: icmp_seq=3 ttl=64 time=0.365 ms
--- 20.0.0.130 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 400ms
rtt min/avg/max/mdev = 0.365/0.433/0.482/0.055 ms
Host 20.0.0.130 is up ###
[root@localhost ~]# ./pinghost.sh 20.0.0.100
PING 20.0.0.100 (20.0.0.100) 56(84) bytes of data.
From 20.0.0.71 icmp_seq=1 Destination Host Unreachable
From 20.0.0.71 icmp_seq=2 Destination Host Unreachable
From 20.0.0.71 icmp_seq=3 Destination Host Unreachable
--- 20.0.0.100 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 410ms
pipe 3
Host 20.0.0.100 is down ###
[root@localhost ~]#
关于"$?"等位置变量和预定义变量,参考博客位置变量和预定义变量部分
case语句
case语句主要使用在:某个变量存在多种取值,需要对其中的每一种取值分别执行不同的命令序列。这种情况和多分支的if语句很相似,只不过if语句需要判断多个不同的条件,而case语句只是判断一个变量的不同取值
注意点如下:
- case行尾必须是单词“in”,每一模式必须以“)”结束
- 双分号“;;”表示命令序列的结束,“esac”表示case结束
- 模式字符串中,可以使用方括号表示一个连续的范围,如:“[0-9]”;还可以用“|”表示或,如“A|B”
- 最后“*)”表示默认模式
语句格式
- case语句格式
case 变量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
…
*)
默认命令序列
esac - 逻辑结构
练习举例:
[root@localhost ~]# vim hitkey.sh
#!/bin/bash
#
read -p "请输入一个字符,并按Enter确认:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您输入的是字母"
;;
[0-9])
echo "您输入的是数字"
;;
*)
echo "您输入的是空格、功能键或其他控制字符"
esac
[root@localhost ~]# chmod +x hitkey.sh
[root@localhost ~]# ./hitkey.sh
请输入一个字符,并按Enter确认:a
您输入的是字母
[root@localhost ~]# ./hitkey.sh
请输入一个字符,并按Enter确认:9
您输入的是数字
[root@localhost ~]# ./hitkey.sh
请输入一个字符,并按Enter确认:.
您输入的是空格、功能键或其他控制字符
[root@localhost ~]#