shell 编程 06 -- shell脚本的条件测试与比较(test、[]、[[]]、(())、read和传参方式的整数比较、打印菜单)
shell编程-6-shell脚本的条件测试与比较
执行条件测试表达式后通常会返回“真”或“假”,就像执行命令后的返回值为0表示真,非0表示假一样
条件测试常用的语法:
条件测试语法 | 说明: |
---|---|
test 测试表达式 | test命令进行条件测试表达式 |
[ 测试表达式 ] | 通过"[]"(单中括号)进行条件测试表达式,同test,推荐使用 |
[[ 测试表达式 ]] | 通过"[[]]"(双中括号)进行条件测试表达式,可以使用通配符等进行模式匹配 |
(( 测试表达式 )) | 通过"(())"(双小括号)进行条件测试表达式,一般用于if语句里,只适用于整数 |
6.1 - shell脚本的条件测试
6.1.1 test 条件测试 -- man test
test条件测试的语法格式为:test <测试表达式>
在test命令中使用-f选项(文件存在且为普通文件则表达式成立)测试文件
在test命令中使用-z选项(如果测试字符串的长度为0,则表达式成立)测试字符串。
` 在test命令中使用-f选项(文件存在且为普通文件则表达式成立)测试文件
[root@zabbix 0506]# touch file
[root@zabbix 0506]# test -f file && echo true || echo false
true
`在test命令中使用-z选项(如果测试字符串的长度为0,则表达式成立)测试字符串。
[root@zabbix 0506]# test -z "oldboy" && echo 1 || echo 0
0
[root@zabbix 0506]# char="oldboy123"
[root@zabbix 0506]# test -z "$char" && echo 1||echo 0
0
[root@zabbix 0506]# char=""
[root@zabbix 0506]# test -z "$char" && echo 1||echo 0
1
6.1.3 [](中括号)条件测试 -- man test
[]条件测试的语法格式为:
[ 测试表达式 ]
注意:中括号内部的两端要有空格,[]和test等价,即test的所有判断选项都可以直接在[]里使用。
[root@zabbix 0506]# [ -f /tmp/moox.txt ] && echo 1||echo 0
1
6.1.4 [[]]条件测试
[[]]条件测试的语法格式为:
[[ 测试表达式 ]]
。 注意:双中括号里的两端也要有空格。
[[]]表达式与[]和test用法的选项部分是相同的,其与[]和test测试表达式的区别在于:
1. 在[[ ]]中可以使用通配符等进行模式匹配;
2. 并且&&、||、>、<等操作符可以应用于[[ ]]中,但不能应用于[ ]中;
3. 在[ ]中一般使用-a、-o、-gt(用于整数)、-lt(用于整数)等操作符代替上文提到的用于[[]]中的符号
[root@zabbix 0506]# [[ -f /tmp/moox.txt ]] && echo 1||echo 0
1
6.2 - 文件测试表达式
6.2.1 常用的文件测试操作符
文件操作符 | 全称 | 说明 |
---|---|---|
-f 文件 | file | 文件存在且为普通文件则真 |
-d 文件 | directory | 文件存在且为目录文件则真 |
-s 文件 | size | 文件存在且文件大小不为0则真 |
-e 文件 | exist | 文件存在则真,区别于-f |
-r 文件 | read | 文件存在且可读则真 |
-w 文件 | write | 文件存在且可写则真 |
-x 文件 | executable | 文件存在且可执行则真 |
-L 文件 | link | 文件存在且为连接文件则真 |
f1 -nt f2 | newer than | 文件f1比文件f2新则真 |
f1 -ot f2 | older than | 文件f1比文件f2旧则真 |
更多... | more | man test |
6.2.2 文件测试表达式举例
(1)普通文件(测试文件类型)
[root@zabbix 0506]# touch oldboy
[root@zabbix 0506]# [ -f oldboy ] && echo 1 || echo 0
1
(2)目录文件(测试文件类型)
[root@zabbix 0506]# mkdir oldgirl
[root@zabbix 0506]# [ -f oldgirl ] && echo 1||echo 0
0
[root@zabbix 0506]# [ -e oldgirl ] && echo 1||echo 0
1
[root@zabbix 0506]# [ -d oldgirl ] && echo 1||echo 0
1
(3)测试文件属性示例
[root@zabbix 0506]# ls -l oldboy
-rw-r--r-- 1 root root 0 May 6 14:08 oldboy
[root@zabbix 0506]# [ -r oldboy ] && echo readable || echo no
readable
[root@zabbix 0506]# [ -w oldboy ] && echo writable || echo no
writable
[root@zabbix 0506]# [ -x oldboy ] && echo executable || echo no
no
[root@zabbix 0506]# chmod +x oldboy
[root@zabbix 0506]# [ -x oldboy ] && echo executable || echo no
executable
`注意:使用root用户时,无论文件权限是怎样的,都是777。区别于其他用户,使用时注意判断用户
(4)多条语句放在一行表示
[root@zabbix 0506]# cat aa.sh
#!/bin/bash
[ -f /tmp/moox.txt ] &&{
echo "moox.txt is a file."
echo "I am oldboy."
}
`等价于一行表示
[root@zabbix 0506]# [ -f /tmp/moox.txt ] && { echo "moox.txt is a file."; echo "I am oldboy.";}
moox.txt is a file.
I am oldboy.
6.3 - 文字测试表达式
6.3.1 字符串测试操作符
操作符 | 理解 | 说明 |
---|---|---|
-z "字符串" ! -z = -n | zero | 若串长度为0则真,-z可以理解为zero [ -z "abd" ]&& echo 1 || echo 0 |
-n "字符串" | no zero | 若串长度不为0则为真,-n可以理解为no zero [ -n "abd" ]&& echo 1 || echo 0 =[ ! -z "abd" ]&& echo 1 || echo 0 |
"串1" = "串2" | equal | 若串1等于串2则为真,==或=均可 test=zhangfd [ "$test" = "zhangfd" ]&& echo 1 || echo 0 |
"串1" != "串2" | not equal | 若串1不等于串2则为真,!==或!=均可 |
注意:符号两端必须有空格 | 以上四条可以man test查看 |
[root@zabbix 0506]# [ -n "abc" ] && echo 1 || echo 0
1
[root@zabbix 0506]# [ -z "abc" ] && echo 1 || echo 0
0
[root@zabbix 0506]# [ "abc" = "11234" ] && echo 1 || echo 0
0
[root@zabbix 0506]# [ "abc" != "11234" ] && echo 1 || echo 0
1
6.4 - 整数二元比较操作符
6.4.1 整数二元比较操作符
比较符,在[] 中使用 | 比较符,在(())或[[]] 中使用,双重括号 | 说明 |
---|---|---|
-eq | = 或 == | equal的缩写,相等 |
-ne | != | not equal的缩写,不相等 |
-gt | > | greater than,大于 |
-ge | ">=" | greater ,equal,大于等于 |
-lt | < | less than,小于 |
-le | "<=" | less,equal,小于等于 |
提示:工作中尽量不要使用双重括号,双重括号是按位比较
[root@zabbix 0506]# a1=98
[root@zabbix 0506]# a2=99
[root@zabbix 0506]# [ $a1 -eq $a2 ] && echo 1|| echo 0
0
[root@zabbix 0506]# [ $a1 -lt $a2 ] && echo 1|| echo 0
1
[root@zabbix 0506]# [ $a1 -gt $a2 ] && echo 1|| echo 0
0
6.5 - 逻辑操作符
6.5.1 逻辑操作符
在[]和test中使用的逻辑操作符 | 在[[]]中使用的逻辑操作符 | 说明 |
---|---|---|
-a | && | and,与,两端都为真,则真 |
-o | || | or,或,两端有一个真则真 |
! | ! | not,非,相反则为真 |
(1)单中括号和双中括号的使用
`[ -a ] 等价于 [[ && ]]
[root@zabbix 0506]# [ -f /etc/hosts -a -f /etc/services ]&& echo 1||echo 0
1
[root@zabbix 0506]# [[ -f /etc/hosts && -f /etc/services ]]&& echo 1||echo 0
1
`[ -o ] 等价于 [[ || ]]
[root@zabbix 0506]# [ 5 -eq 6 -o 5 -gt 3 ] && echo 1||echo 0
1
[root@zabbix 0506]# [[ 5 -eq 6 || 5 -gt 3 ]] && echo 1||echo 0
1
(2)多个条件的连接
[root@zabbix 0506]# m=21;n=36
[root@zabbix 0506]# [ $m -gt 20 -a $n -lt 30 ]&& echo 1||echo 0
0
[root@zabbix 0506]# [ $m -gt 20 ]&&[ $n -lt 30 ]&& echo 1||echo 0
0
[root@zabbix 0506]# [ $m -gt 20 ]||[ $n -lt 30 ]&& echo 1||echo 0
1
6.5.2 脚本传参和read方式比较两个整数大小
开发Shell脚本,分别实现以脚本传参和read读入的方式比较两个整数的大小。
用条件表达式(禁止用if)进行判断并以屏幕输出的方式提醒用户比较的结果。
注意:一共是开发两个脚本。在用脚本传参和read读入的方式实现时,需要对变量是否为数字及传参个数是否正确给予提示。
参考答案1:采用read方法。
[root@zabbix 0506]# cat compare_read.sh
#!/bin/bash
read -p "Please input two int nums:" numa numb
[ -z $numa ] || [ -z $numb ] && {
echo "pls input two int nums not zero"
exit 1
}
expr $numa + $numb + 1 &>/dev/null
ret_val=$?
test $ret_val -eq 0 ||{
echo "the two nums not int,pls input again."
exit 2
}
[ $numa -lt $numb ] && {
echo "$numa < $numb"
exit 0
}
[ $numa -gt $numb ] && {
echo "$numa > $numb"
exit 0
}
[ $numa -eq $numb ] && {
echo "$numa = $numb"
exit 0
}
--------------------------------------------
[root@zabbix 0506]# sh compare_read.sh
Please input two int nums:11 22
11 < 22
[root@zabbix 0506]# sh compare_read.sh
Please input two int nums:11 11
11 = 11
[root@zabbix 0506]# sh compare_read.sh
Please input two int nums:11 1
11 > 1
[root@zabbix 0506]#
参考答案2:采用传参方法。
[root@zabbix 0506]# cat compare_chuancan.sh
#!/bin/bash
# read -p "Please input two int nums:" numa numb
numa=$1
numb=$2
[ -z $numa ] || [ -z $numb ] && {
echo "USAGE: $0 num1 num2"
exit 1
}
expr $numa + $numb + 1 &>/dev/null
ret_val=$?
test $ret_val -eq 0 ||{
echo "the two nums not int,pls input again."
exit 2
}
[ $numa -lt $numb ] && {
echo "$numa < $numb"
exit 0
}
[ $numa -gt $numb ] && {
echo "$numa > $numb"
exit 0
}
[ $numa -eq $numb ] && {
echo "$numa = $numb"
exit 0
}
-----------------------------------------------------------
[root@zabbix 0506]# sh compare_chuancan.sh 11 12
11 < 12
[root@zabbix 0506]# sh compare_chuancan.sh 11 11
11 = 11
[root@zabbix 0506]# sh compare_chuancan.sh 11 10
11 > 10
[root@zabbix 0506]#
6.5.3 打印选择菜单
打印选择菜单,按照选择项一键安装不同的Web服务。
[root@zabbix 0507]# cat menu.sh
#!/bin/bash
Path=/server/scripts
[ ! -d $Path ]&& mkdir -p $Path
cat << zfd ## 指定格式打印多行文本的cat用法
1.[install lamp]
2.[install lnmp]
3.[exit]
zfd
read -p "Please input the num you want:" num
## 输入值判空
[ -z $num ] && {
echo "you must input a num."
exit 2
}
## 整数判断
expr $num + 1 &>/dev/null
ret=$?
[ $ret -ne 0 ] &&{
echo "the num must be {1|2|3}"
exit 1
}
[ $num -eq 1 ]&&{
echo "start installing lamp"
[ -e ${Path}/lamp.sh ] ||{
echo "${Path}/lamp.sh not exist."
exit 1
}
[ -x ${Path}/lamp.sh ] ||{
echo "${Path}/lamp.sh can not be exec."
exit 1
}
.${Path}/lamp.sh &>/dev/null
echo "lamp is installed."
exit 0
}
[ $num -eq 2 ]&&{
echo "start installing lnmp"
[ -e ${Path}/lnmp.sh ] ||{
echo "${Path}/lnmp.sh not exist."
exit 1
}
[ -x ${Path}/lnmp.sh ] ||{
echo "${Path}/lnmp.sh can not be exec."
exit 1
}
.${Path}/lnmp.sh &>/dev/null
echo "lnmp is installed."
exit 0
}
[ $num -eq 3 ]&&{
echo exit
exit 0
}
## 整数匹配
[[ ! $num = ~[1-3] ]] && {
echo "the num you input must be {1|2|3}"
echo "Input error."
exit 4
}
[root@zabbix 0507]# sh menu.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
Please input the num you want:
6.6 - 测试表达式的区别总结
6.6.1 - test、[]、[[]]、(())的区别总结
测试表达式符号 | [] | test | [[]] | (()) |
---|---|---|---|---|
边界空格 | 需要 | 需要 | 需要 | 不需要 |
逻辑操作符 | ! 、-a 、-o | ! 、-a 、-o | ! 、&&、|| | ! 、&&、|| |
整数比较操作符 | -eq,-gt,-lt,-ge,-le | -eq,-gt,-lt,-ge,-le | -eq,-gt,-lt,-ge,-le或=,>,<,>=,<=,!= | =,>,<,>=,<=,!= |
字符串比较操作符 | =,==,!= | =,==,!= | =,==,!= | =,==,!= |
匹配通配符 | 不支持 | 不支持 | 支持 | 不支持 |
作者:moox
出处:http://www.cnblogs.com/moox/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。