六、shell脚本的条件测试与比较
(一)条件表达式的常见语法
1、条件表达式6种写法(if,while)
语法1:test<测试表达式>
语法2:[ <测试表达式>] #中括号两端必须要有空格
语法3:[[<测试表达式>]] #两端必须要有空格
语法4:((测试表达式)) #两端必不需要空格
语法5:(命令表达式)
语法6:命令表达式
实际应用展示
①[]条件表达式
[root@centos6-kvm3 scripts]# [ -e /etc/hosts ] && echo 0 || echo 1
0
[root@centos6-kvm3 scripts]# [ -e /etc/host1 ] && echo 0 || echo 1
1
②test条件表达式:test和[]功能相同
[root@centos6-kvm3 scripts]# test -e /etc/host1 && echo 0 || echo 1
1
[root@centos6-kvm3 scripts]# test -e /etc/hosts && echo 0 || echo 1
0
[root@centos6-kvm3 scripts]# # [] == test
③[[]]双中括号条件表达式,两边需要空格
[root@centos6-kvm3 scripts]# [[ -e /etc/host1 ]] && echo 0 || echo 1
1
[root@centos6-kvm3 scripts]# [[ -e /etc/hosts ]] && echo 0 || echo 1
0
④双括号条件表达式,两边不需要空格
[root@centos6-kvm3 scripts]# (( -e /etc/hosts )) && echo 0 || echo 1
-bash: ((: -e /etc/hosts : division by 0 (error token is "/hosts ")
1
⑤双括号一般用于计算:
[root@centos6-kvm3 scripts]# ((3>5)) && echo 0 || echo 1
1
[root@centos6-kvm3 scripts]# ((3<5)) && echo 0 || echo 1
0
[root@centos6-kvm3 scripts]# #(())用于计算
⑥expr 表达式:使用括号
[root@centos6-kvm3 scripts]# (expr 1 + 2 &>/dev/null) && echo 0 || echo 1
0
[root@centos6-kvm3 scripts]# (expr 1 + 2 &>/dev/null) && echo 0 || echo 1
0
[root@centos6-kvm3 scripts]# (expr 1 + a &>/dev/null) && echo 0 || echo 1
1
⑦expr 表达式:使用反引号
[root@centos6-kvm3 scripts]# `expr 1 + a &>/dev/null` && echo 0 || echo 1
1
[root@centos6-kvm3 scripts]# `expr 1 + 2 &>/dev/null` && echo 0 || echo 1
0
[root@centos6-kvm3 scripts]#
(二)条件表达式的编辑语法:
1、[<测试表达式>] && 命令1 ||命令2
如果前面表达式成功,那么执行命令1,否则执行命令2
if [ <测试表达式>]
then
命令1
else
命令2
fi
2、多命令情况
当命令很多的时候,我们可以使用大括号把所有命令括起来。如下:
[ <测试表达式> ] && {
命令1
命令2
}||{
命令3
命令4
}
3、只保留执行成功的
[ <测试表达式>] &&{
命令1
命令2
命令3
}
4、只保留执行失败的
[<测试表达式>] || {
命令1
命令2
命令3
}
(三)文件测试表达式
man test
-d:文件为目录且存在
[root@centos6-kvm3 scripts]# [ -d /etc/hosts ] && echo 0 || echo 1
1
[root@centos6-kvm3 scripts]# [ -d /etc ] && echo 0 || echo 1
0
-f:判断为文件且存在
[root@centos6-kvm3 scripts]# [ -f /etc/hosts ] && echo 0 || echo 1
0
-e:判断存在,为目录或者文件
[root@centos6-kvm3 scripts]# [ -e /etc/hosts ] && echo 0 || echo 1
0
[root@centos6-kvm3 scripts]# [ -e /etc ] && echo 0 || echo 1
0
-r:判断文件为可读:
[root@centos6-kvm3 scripts]# [ -r /etc/hosts ] && echo 0 || echo 1
0
[root@centos6-kvm3 scripts]# ll /etc/hosts
-rw-r--r--. 2 root root 352 Nov 19 2018 /etc/hosts
-x:判断文件为可执行:
[root@centos6-kvm3 scripts]# [ -x /etc/hosts ] && echo 0 || echo 1
1
[root@centos6-kvm3 scripts]# chmod +x /etc/hosts
[root@centos6-kvm3 scripts]# [ -x /etc/hosts ] && echo 0 || echo 1
0
-s:判断文件大小不为0:
[root@centos6-kvm3 scripts]# [ -s /etc/hosts ] && echo 0 || echo 1
0
[root@centos6-kvm3 scripts]# touch oldboy.log
[root@centos6-kvm3 scripts]# [ -s oldboy.log ] && echo 0 || echo 1
1
应用示例:crond
[root@centos6-kvm3 scripts]# cat /etc/init.d/crond
(四)字符串测试表达式的常见功能说明
n:not zero ,[-n "字符串" ] 字符串长度不为0,表达式为真。
z:zero,[-z "字符串" ] 字符串长度为0,表达式为真。
["字符串1"==“字符串2”] 两个字符串相同为真。
[“字符串1”!=“字符串2”] 两个字符串不相同为真。
注意:
1、字符串就用双引号。
2、等号可以用一个或者两个。
3、等号两端必须要有空格。
[root@centos6-kvm3 scripts]# [ -n "oldboy" ] && echo 1 || echo 0
1
[root@centos6-kvm3 scripts]# [ -z "oldboy" ] && echo 1 || echo 0
0
[root@centos6-kvm3 scripts]# char="oldboy"
[root@centos6-kvm3 scripts]# [ -n "$char" ] && echo 1 || echo 0
1
[root@centos6-kvm3 scripts]# unset char
[root@centos6-kvm3 scripts]# [ -n "$char" ] && echo 1 || echo 0
0
[root@centos6-kvm3 scripts]# [ "dd"=="ff" ] && echo 1 || echo 0
1
[root@centos6-kvm3 scripts]# [ "dd" == "ff" ] && echo 1 || echo 0
0
[root@centos6-kvm3 scripts]# [ "dd" == "dd" ] && echo 1 || echo 0
1
[root@centos6-kvm3 scripts]# [ "dd" != "ff" ] && echo 1 || echo 0
1
[root@centos6-kvm3 scripts]# [ "dd" != "dd" ] && echo 1 || echo 0
0
实例应用:
cat /etc/init.d/crond
cat /etc/init.d/network
实例:
[root@centos6-kvm3 scripts]# cat select1.sh
#!/bin/bash
cat << EOF
1.install lamp
2.install lnmp
3.exit
EOF
read -p "请输入一个序号:" num
[ -z "$num" ] && exit 1 #判断内容是否为空
expr 2 + $num &>/dev/null
if [ $? -ne 0 ]
then
echo "usage:$0{1|2|3}"
exit 1
fi
if [ $num -eq 1 ]
then
echo "install lamp..."
elif [ $num -eq 2 ]
then
echo "install lnmp ..."
elif [ $num -eq 3 ]
then
echo "bye..."
exit
else
echo "usage:$0{1|2|3}"
exit 1
fi
(五)整数测试表达式
在[]及test中使用的比较表达式 | 在(())和[[]]中使用的比较符号 | 说明 |
---|---|---|
-eq | ==或者= | 等于equal |
-ne | != | 不等于not equal |
-gt | > | 大于greater then |
-ge | >= | 大于等于greater equal |
-lt | < | 小于 less then |
-le | <= | 小于等于 less equal |
实例
[root@centos6-kvm3 ~]# [ 2 -eq 3 ] && echo 0 || echo 1
1
[root@centos6-kvm3 ~]# [ 2 -gt 3 ] && echo 0 || echo 1
1
[root@centos6-kvm3 ~]# [ 2 -lt 3 ] && echo 0 || echo 1
0
[root@centos6-kvm3 ~]# [ 2 > 3 ] && echo 0 || echo 1
0
[root@centos6-kvm3 ~]# [ 2 \> 3 ] && echo 0 || echo 1
1
[root@centos6-kvm3 ~]# [[ 2 > 3 ]] && echo 0 || echo 1
1
[root@centos6-kvm3 ~]# [[ 2 -gt 3 ]] && echo 0 || echo 1
1
[root@centos6-kvm3 ~]# [[ 2 -lt 3 ]] && echo 0 || echo 1
0
[root@centos6-kvm3 ~]# (( 2 -lt 3 )) && echo 0 || echo 1
-bash: ((: 2 -lt 3 : syntax error in expression (error token is "3 ")
1
[root@centos6-kvm3 ~]# (( 2 > 3 )) && echo 0 || echo 1
1
[root@centos6-kvm3 ~]# (( 2 < 3 )) && echo 0 || echo 1
0
[root@centos6-kvm3 ~]# test 2 -gt 3 && echo 0 || echo 1
1
[root@centos6-kvm3 ~]# test 2 -lt 3 && echo 0 || echo 1
0
总结:
1、双中括号中使用 字母表达式。
2、双括号中不适合字母表达式,只适合符号表达式。
3、test表达式只适合符号表达式。
(六)测试题:使用read的交互方式,来比较两个整数的大小。
[root@centos6-kvm3 scripts]# cat test3.sh
#!/bin/bash
read -p "请输入两个整数:" a b
[ -z "$b" ] && {
echo "请输入两个整数。"
exit 1
}
expr $a + $b + 1 &>/dev/null
[ $? -ne 0 ] && {
echo "请输入两个整数。"
exit 2
}
[ $a -lt $b ] && {
echo "$a小于$b."
exit 0
}
[ $a -gt $b ] && {
echo "$a大于$b."
exit 0
}
[ $a -eq $b ] && {
echo "$a等于$b."
exit 0
}
================
使用if语句:
[root@centos6-kvm3 scripts]# cat test4.sh
#!/bin/bash
read -p "请输入两个整数:" a b
[ -z "$b" ] && {
echo "请输入两个整数。"
exit 1
}
expr $a + $b + 1 &>/dev/null
[ $? -ne 0 ] && {
echo "请输入两个整数。"
exit 2
}
if [ $a -lt $b ]
then
echo "$a小于$b."
elif [ $a -gt $b ]
then
echo "$a大于$b."
else
echo "$a等于$b."
fi
[root@centos6-kvm3 scripts]#
(七)逻辑测试表达式
在[]和test中使用操作符 | 在[[]]和(())中使用操作符 | 说明 |
---|---|---|
-a | && | and 与 |
-o | || | or 或 |
! | ! | not 非 |
实例:
[root@centos6-kvm3 scripts]# [ 1 -eq 1 -a -f /etc/hosts ] && echo 1 || echo 0
1
[root@centos6-kvm3 scripts]# [ 1 -eq 2 -a -f /etc/hosts ] && echo 1 || echo 0
0
[root@centos6-kvm3 scripts]# [ 1 -eq 2 -o -f /etc/hosts ] && echo 1 || echo 0
1
[root@centos6-kvm3 scripts]# [ 1 -eq 2 ] -o [ -f /etc/hosts ] && echo 1 || echo 0
-bash: [: too many arguments
0
[root@centos6-kvm3 scripts]# [ 1 -eq 2 ] || [ -f /etc/hosts ] && echo 1 || echo 0
1
[root@centos6-kvm3 scripts]# [ 1 -eq 2 ] && [ -f /etc/hosts ] && echo 1 || echo 0
0
[root@centos6-kvm3 scripts]# [[ 1 -eq 2 || -f /etc/hosts ]] && echo 1 || echo 0
1
[root@centos6-kvm3 scripts]# [[ 1 -eq 2 && -f /etc/hosts ]] && echo 1 || echo 0
0