条件测试命令,if命令,双圆括号,双中括号
本篇主要是对条件测试、if命令、(( ))、[[ ]]进行说明,如有不当之处,敬请留言指正。
一、条件测试命令:
格式1:test 条件表达式
格式2:[ 条件表达式 ]
测试的条件类型:
- 测试文件状态
- 整数值比较
- 字符串比较
- 逻辑测试
1.文件测试
格式:[ 操作符 文件或目录 ]
常用的测试操作符:
- -d:测试是否为目录(directory)
- -e:测试目录或文件是否存在(exist)
- -f:测试是否为文件(file)
- -s:测试文件存在且内容非空(仅有1个空格也是非空)
- -r:测试当前用户是否有权限读取(read)
- -w:测试当前用户是否有权限写入(write)
- -x:测试当前用户是否有权限执行(execute)
后面接#echo $? –》返回值为0,则上一条执行正确,为1,则执行错误。
经典用法:
[ -d /backup ]&&echo "/backup directory is exist"||mkdir /backup
这段代码的含义是:判断根下的backup目录是否存在,如果存在就输出”/backup directory is
exist”,如果不存在就创建/backup目录。
执行结果:
2.整数值比较
(1)传统格式:[ 整数1 操作符 整数2 ]
常用的测试操作符:
- -eq:等于(equal)
- -ne:不等于(not equal)
- -gt:大于(greater than)
- -lt:小于(lesser than)
- -le:小于或等于(lesser or equal)
- -ge:大于或等于(greater or equal)
(2)双圆括号比较: 格式:(( 整数1 操作符 整数2 ))
推荐使用双圆括号法比较整数值
# a=10
# ((a>20)) && echo ok || echo no
no
#((a>b))
#[ $b -gt $a ];echo $? --》不能使用> < >= ==
练习1:
# who | wc -l
7
# [ $(who | wc -l) -gt 5 ] && echo "Too many."
--》用户数是否>5
Too many.
# [ $(who | wc -l) -ge 10 ] && echo "> = 10."
--》用户数是否>=10
练习2:
监控内存的使用情况,一旦内存的可用空间低于800M就在屏幕上输出“your system is less than 800M,you need to do something to improve memory size”(用free -m 命令即可)。
答案:
# a=$(free -m|grep "Mem"|tr -s ' '|awk '{print $4}')
# [ $a -lt 800 ]&&echo "your system is less than 800M"
3.字符串比较
(1)
格式1:
[ 字符串1 = 字符串2 ]
[ 字符串1 != 字符串2 ]
格式2:
[ -z 字符串 ]
- -z:字符串内容为空
- -n:字符串内容非空
判断字符串时,建议都加“”
例子:
(2)双方括号进行字符串比较–》推荐
格式:[[ 字符串1=字符串2 ]]
(方括号时,要用-gt等等符号 )
[[ ]] 可以解决变量中带空格的问题!!
# [ $a = "abc 123" ] && echo ok || echo no
-bash: [: too many arguments
no
# [[ $a = "abc 123" ]] && echo ok || echo no
ok
PS:
# a=cc
# [[ $a=="ccc" ]]
# echo $?
0 ==》系统把[[]]里面的语句当作了一条命令,并没有比较!!
# [[ $a == "ccc" ]] --》在等号前后分别加空格即可!!
# echo $?
1
可以使用通配符:
# cat test.sh
#!/bin/bash
[[ $1 = ??? ]] && echo ok || echo no --》匹配任意三个字符
# ./test.sh ab
no
# ./test.sh abc
ok
# cat test.sh
#!/bin/bash
[[ $1 = a* ]] && echo ok || echo no --》匹配以a开头的
# ./test.sh bbba
no
# ./test.sh abb
ok
# cat test.sh
read -s -p "please input password: " pass
[[ $pass = ???* ]] && echo passwd is ok || echo passwd too short
--》判断密码的长度至少为3位
练习1:设置密码
判断用户是否存在,存在则设置密码,不存在就新建,然后给用户设置密码,用户输入的密码长度小于6位时给与提醒,弱密码,如果大于6位,提醒用户设置的密码长度,并且提示安全。
答案:
#!/bin/bash
read -p "Please input the user:" u_name
if id u_name
then
read -p "Please input the passwds:" pass
len=echo $pass|wc -m --》统计密码的长度
echo $pass|passwd $u_name&>/dev/null
else
echo "The user u_name isn't exit!!"
useradd u_name && echo "User u_name create OK!!"
read -p "Please input the passwds:" pass
echo $pass|passwd $u_name&>/dev/null
fi
[[ $pass = ?????? ]] && echo "passwd is OK!And the lens is $(($len-1)) ,it‘s so good!!"||echo "passwd is so short!!"
怎么得到密码的长度?
方法①:
#a=123
#len=echo ${#a} --》非常准确!
方法②:
len=echo $a|wc -m --》得到的值比实际大1
PS:bash自带的处理字符串:
- echo ${#a}
- $a中字符串的个数
- echo ${a:3}
- $a中从第三个开始取值直到结束
- echo ${a:3:2}
- $a中从第三个开始取两个字符
- echo ${a: -1}
- 取最后一个字符
- echo ${a#*.}
- 从左边开始删除直到遇到 . (句号)为止
- echo ${a##*.}
- 从左边开始删除直到遇到最后一个句号为止
- echo ${a%.*}
- 从右面开始删除直到遇到句号为止
- echo ${a%%.*}
- 从右面开始删除直到遇到最后一个句号为止
- echo ${a/abc/111}
- 将变量a中第一个abc替换成111
- echo ${a//abc/xyz}
- 将变量a中的所有的abc替换成xyz
练习2 :新建用户
提示用户输入用户名,判断用户是否存在,如果存在,要提醒用户是否删除并新建,输入yes就删除,输入no则不删除;用户不存在时,也提醒用户不存在,输入yes新建,输入no则不新建。
答案:
#!/bin/bash
read -p "Please input the Username:" U_name
if id $U_name
then
read -p "Would you like to delete this user?(yes/no)" a
if [ $a = "yes" ]
then
userdel -r $U_name&&echo "U_name deleted OK!!!"
else
echo "You choose don't delete!"
fi
else
read -p "Would you like to creat U_name?(yes/no)" b
if [ $b = "yes" ]
then
useradd $U_name&&echo "User $U_name created OK!!!"
else
echo "You choose don't create!"
fi
fi
小结:
- (()) :推荐作数值比较
- [] :字符串和数值比较
- [[]] :字符串和数值比较,推荐作字符串比较
4.逻辑测试
格式1:[ 表达式1 ] &&或|| [ 表达式2 ] …
格式2:[ 表达式1 -a或-o 表达式2 ] …
- -a或&& 表示逻辑与,是“而且”的意思
- 前后两个表达式都成立时整个测试结果才为真,否则为假。
- -o或|| 是逻辑或,是“或者”的意思
- 操作符两边至少一个为真时,结果为真,否则结果为假
- !:逻辑否。
- 当指定的条件不成立时,返回结果为真。
练习:使用条件测试完成下列任务
(1)测试/分区磁盘空间,小于10%,显示“一切正常”,否则显示“当前的磁盘空间是磁盘空间% 警告”
(2)统计当前系统的登陆用户,登陆用户小于3个,显示“一切正常”,否则显示“登陆用户已经有:个数”
(3)测试当前主机eth0的网卡入站和出站流量,只要两个都大于200MiB,就显示“警告”;
(4)当内存空闲空间小于内存的5%时,显示“内存不足”,否则显示“当前空闲内存是:内存空闲数值”
答案:
(1)#df -Th
#!/bin/bash
a=$(df -Th|grep sda3|tr -s ' '|awk '{print $6}'|tr -d %)
if (( $a<10 ))
then
echo "Everything is OK!"
else
echo "Now is:$a % free space!"
fi
(2)#who
#!/bin/bash
a=$(who|wc -l)
(($a<3))&&echo "Everything is OK!"||echo "The user is: $a "
(3)#watch -n 1 "/sbin/ifconfig eth0“
watch -n 1 "/sbin/ifconfig eth0|grep bytes|tr -s ' '|cut -d ' ' -f8|tr -d '(' ")
(4)#free
#!/bin/bash
free=$(free|grep "Mem"|tr -s ' '|awk -F ' ' '{print $4}')
tocal=$(free|grep "Mem"|tr -s ' '|awk -F ' ' '{print $2}')
echo "The free space is: $free"
echo "The tocal space is:$tocal"
bai=$(echo -n 0;echo "scale=2;$free/$tocal"|bc)
bai_xin=$(echo $bai|tr -d '0.')
echo "$bai_xin"
(($bai_xin<5))&&echo "The mem isn't enough!!"||echo "当前空闲内存是:$free,空闲百分比:$bai_xin%"
效果:
练习:
将access.log 文件里的web日志访问次数最多的10个ip地址,显示出来要求格式如下:
1 172.16.30.123 tocal:1898
2 172.16.30.34 tocal:1800
3 172.16.20.13 tocal:1456
答案:
#cat access.log | cut -d ” ” -f1 | sort | uniq -c | sort -k1 -nr | head | tr -s “ “| cat -n | awk -F “ ” ‘{print
分析:
截取文件里的ip–》相同ip在一起–》去重统计–》按第一列的数值大小降序–》取前十个–》压缩空格–》产生行号–》截取1,3,2列
效果:
方法2:
二、if语句
格式:
(1)单分支:
if
then
语句
fi
(2)双分支:
if
then
语句
else
语句
fi
(3)多分支:
if
then
语句
elif
then
语句
...
else
语句
fi
练习:
按成绩分层次输出优秀、及格等等信息。
#!/bin/bash
read -p "Please input the score:" score
if (($score>=90))&&(($score<=100))
then
echo "成绩优秀!"
elif(($score>=61))&&(($score<=89))
then
echo "成绩及格!"
elif (($score==60))
then
echo "及格万岁!"
elif (($score<60))
then
echo "你需要补考!"
else
echo "应该是0-100的数,输入错误!"
fi
PS:
- ^[0-9]*$ 匹配只是数字的数值,不包含字母
- ^ 代表以什么开头
- $ 代表以什么结尾
- [0-9] 代表数字0-9
- - 代表前面的字符有0个或者多个
练习:
检查整个局域网中172.16.30.0/16,172.16.30.1到30.254之间的ip,有哪些ip正在使用,哪些没有使用;显示出正在使用的ip地址和总数。
#!/bin/bash
#实验时把255改成180 200即可
for b in `seq 255`
do
ip=172.16.30.$b
echo $ip
(ping $ip -c 1 -i 0.2 -w 1 &>/dev/null )&
if (( $?==0 ))
then
echo "$ip is UP" >>IPADD2.txt
else
echo "$ip is DOWN" >>IPADD2.txt
fi
done
sleep 3
num_up=`cat IPADD2.txt | grep UP | wc -l`
num_down=`cat IPADD2.txt | grep DOWN | wc -l`
echo "There are $num_up computers UP."
echo "There are $num_down computers DOWN."