返回顶部

zhangfd

个人博客,仅供学习使用

导航

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或=,>,<,>=,<=,!= =,>,<,>=,<=,!=
字符串比较操作符 =,==,!= =,==,!= =,==,!= =,==,!=
匹配通配符 不支持 不支持 支持 不支持

posted on 2020-05-07 11:45  zhangfd  阅读(568)  评论(0编辑  收藏  举报