shell条件测试

shell脚本的智能化

  • 使用shell脚本获得识别能力?
  • 为命令的执行提供最直接的识别依据
    文件或目录的读/写等等状态
    数值的大小
    字串符是否匹配
    多条件组合

test测试条件的基本用法

  • 语法格式:
  • 表达式两边至少要留一个空格
  • help test 查阅帮助
    test 选项 参数
    [ 选项 参数 ]

字串符比较

  • [ 字串符1 操作符 字串符2 ]
操作符 含义
== 两个字串符相同
!= 两个字串符不相同
-z 字串符的值为空
!= 字串符的值不为空(相当于! -z)
[root@proxy opt]# test a ==  a  ##判断字串符a是否等于a
[root@proxy opt]# echo $?         ##查看结果,0代表成功,非0为失败
0
[root@proxy opt]# test a ==  b
[root@proxy opt]# echo $?
1
[root@proxy opt]# [ a == a ]    ##另一种格式,效果同上,字符串两边有空格
[root@proxy opt]# echo $?
0
[root@proxy opt]# [ a == b ]
[root@proxy opt]# echo $?
1
[root@proxy opt]# [ $USER == root ]  ##判断当前用户名是否为root
[root@proxy opt]# echo $?
0
[haha@proxy ~]$ [ $USER == root ]
[haha@proxy ~]$ echo $?
1
[haha@proxy ~]$ [ $USER != root ]  ##判断当前用户是否不是root
[haha@proxy ~]$ echo $?            ##查看结果
0
[root@proxy ~]$ [ a != b ]    ##判断字符串a是否不等于字符串b
[root@proxy ~]$ echo $?       ##查看结果
0
[root@proxy ~]$ [ a != a ]     
[root@proxy ~]$ echo $?
1
[root@proxy ~]$ [ -z $a ]    ##判断变量a是否为空值
[root@proxy ~]$ echo $?      ##查看结果
0
[root@proxy ~]$ a=10       
[root@proxy ~]$ [ -z $a ]   
[root@proxy ~]$ echo $?
1
[root@proxy opt]# [ $a == b ]   ##判断变量a是否等于b,如果变量a为空则报错
[root@proxy opt]# echo $?        
1
[root@proxy opt]# a=b                
[root@proxy opt]# [ "$a" ==  b ]  
[root@proxy opt]# echo $?
0
[root@proxy opt]# [ ! -z $a ]   ##判断变量a是否为非空值
[root@proxy opt]# echo $?
0

注意事项:
-bash: [: a==: unary operator expected
-bash: [: a==: 期待一元表达式
出现以上信息则代表格式有误,或者变量值为空值.

逻辑分隔符操作

  • 主要用法:
  • 命令1 操作符 命令2 …
  • [条件1] 操作符 [条件2] …
类型      含义
&&       给定条件都必须成立,整个测试结果为真
||       只要其中一个条件成立,则整个测试结果为真

逻辑判断:
&& 并且 符号之前命令成功才执行后面的命令
|| 或者 符号之前的命令执行失败才执行后面的任命令

当使用2个逻辑符号时:
&& 前后任务都成功才算成功
|| 前后有一个任务成功就算成功


[root@proxy opt]# ls && ls && ls   ##第1个成功,第2个成功,第3个成功
10.txt  4.txt  8.txt  c.sh  g.sh              nginx-1.12.2  test04.sh  xyz
1.txt   5.txt  9.txt  d.sh  h.sh              test01.sh     test05.sh
2.txt   6.txt  a.sh   e.sh  lnmp_soft         test02.sh     test06.sh
3.txt   7.txt  b.sh   f.sh  lnmp_soft.tar.gz  test03.sh     test07.sh
10.txt  4.txt  8.txt  c.sh  g.sh              nginx-1.12.2  test04.sh  xyz
1.txt   5.txt  9.txt  d.sh  h.sh              test01.sh     test05.sh
2.txt   6.txt  a.sh   e.sh  lnmp_soft         test02.sh     test06.sh
3.txt   7.txt  b.sh   f.sh  lnmp_soft.tar.gz  test03.sh     test07.sh
10.txt  4.txt  8.txt  c.sh  g.sh              nginx-1.12.2  test04.sh  xyz
1.txt   5.txt  9.txt  d.sh  h.sh              test01.sh     test05.sh
2.txt   6.txt  a.sh   e.sh  lnmp_soft         test02.sh     test06.sh
3.txt   7.txt  b.sh   f.sh  lnmp_soft.tar.gz  test03.sh     test07.sh
[root@proxy opt]# ls || ls || ls   ##第1个成功,第2个不执行,前面任务算成功,第3个不执行
10.txt  4.txt  8.txt  c.sh  g.sh              nginx-1.12.2  test04.sh  xyz
1.txt   5.txt  9.txt  d.sh  h.sh              test01.sh     test05.sh
2.txt   6.txt  a.sh   e.sh  lnmp_soft         test02.sh     test06.sh
3.txt   7.txt  b.sh   f.sh  lnmp_soft.tar.gz  test03.sh     test07.sh
[root@proxy opt]# ls &&ls ||ls     ##第1个成功,第2个成功,前面任务算成功,第3个不执行
10.txt  4.txt  8.txt  c.sh  g.sh              nginx-1.12.2  test04.sh  xyz
1.txt   5.txt  9.txt  d.sh  h.sh              test01.sh     test05.sh
2.txt   6.txt  a.sh   e.sh  lnmp_soft         test02.sh     test06.sh
3.txt   7.txt  b.sh   f.sh  lnmp_soft.tar.gz  test03.sh     test07.sh
10.txt  4.txt  8.txt  c.sh  g.sh              nginx-1.12.2  test04.sh  xyz
1.txt   5.txt  9.txt  d.sh  h.sh              test01.sh     test05.sh
2.txt   6.txt  a.sh   e.sh  lnmp_soft         test02.sh     test06.sh
3.txt   7.txt  b.sh   f.sh  lnmp_soft.tar.gz  test03.sh     test07.sh
[root@proxy opt]# ls || ls && ls   ##第1个成功,第2个不执行,前面任务算成功,第3个成功
10.txt  4.txt  8.txt  c.sh  g.sh              nginx-1.12.2  test04.sh  xyz
1.txt   5.txt  9.txt  d.sh  h.sh              test01.sh     test05.sh
2.txt   6.txt  a.sh   e.sh  lnmp_soft         test02.sh     test06.sh
3.txt   7.txt  b.sh   f.sh  lnmp_soft.tar.gz  test03.sh     test07.sh
10.txt  4.txt  8.txt  c.sh  g.sh              nginx-1.12.2  test04.sh  xyz
1.txt   5.txt  9.txt  d.sh  h.sh              test01.sh     test05.sh
2.txt   6.txt  a.sh   e.sh  lnmp_soft         test02.sh     test06.sh
3.txt   7.txt  b.sh   f.sh  lnmp_soft.tar.gz  test03.sh     test07.sh
检查变量X的值是否大于10,且小于30:
[root@proxy ~]# X=20                 ##设置X变量的值为20
[root@proxy ~]# [ $X -gt 10 ] && [ $X -lt 30 ] && echo "YES"
YES
只要/tmp/、/var/spool/目录中有一个可写,则条件成立:
[root@proxy ~]# [ -w "/tmp/" ] || [ -w "/var/spool/" ] && echo "OK"
OK

整数值比较

  • [整数值1 操作符 整数值2 ]
操作符 含义
-eq 等于
-ne 不等于
-ge 大于或等于
-le 小于或等于
-gt 大于
-lt 小于
[root@proxy opt]# [ 10 -ne 10 ] && echo "OK" || echo "no"  
no
[root@proxy opt]# [ 10 -le 11 ] && echo "OK" || echo "no"
OK
[root@proxy opt]# [ 1 -eq 1 ]
[root@proxy opt]# echo $?
0
[root@proxy opt]# a=10
[root@proxy opt]# [ 10 -eq $a ]  ##支持变量
[root@proxy opt]# echo $?
0

编写一个监控脚本,检查系统登录的账户数量

[root@proxy opt]# vim test08.sh  
#!/bin/bash
x=`who | wc -l`  ##统计当前登录的用户数量
[ $x -eq 3 ] && echo "有人入侵服务器~!" | mail -s test root  ##超过3个就发邮件给管理员
[root@proxy opt]# chmod +x test08.sh   ##给脚本添加执行权限
[root@proxy opt]# crontab -e   ##写进周期性计划任务里实现每两分钟自动发送邮件给管理员
*/2 * * * *  /opt/test08.sh

编写一个监控用户数量的脚本

[root@proxy opt]# vim test14.sh
#!/bin/bash
#这是一个简单的监控用户数量的测试脚本
x=`cat /etc/passwd | wc-l`
[ $x -ne 31] && echo "有人篡改账户,目前账户数量是$x" | mail -s test root
[root@proxy opt]# chmod +x test14.sh   ##给脚本添加执行权限

文件状态测试

  • [ 操作符 文件或目录 ]
操作符 含义
-e 判断对象是否存在,若存在则结果为真
-d 判断对象是否为目录,是则为真
-f 判断对象是否为一般文件,是则为真
-r 判断对象是否有可读权限,是则为真
-w 判断对象是否有可写权限,是则为真
-x 判断对象是否有可执行,是则为真
[root@proxy opt]# [ -e /opt/123 ]    ##测试123是否存在,不关心文件类型
[root@proxy opt]# echo $?
1
[root@proxy opt]# [ -f /opt/123 ]   ##测试123是否存在,必须是普通文件
[root@proxy opt]# echo $?
1
[root@proxy opt]# [ -e /opt/abc ]   
[root@proxy opt]# echo $?
1
[root@proxy opt]# [ -f /opt/abc ]    
[root@proxy opt]# echo $?
1
[root@proxy opt]# mkdir abc
[root@proxy opt]# [ -e /opt/abc ]      ##测试abc是否存在,不关心文件类型
[root@proxy opt]# echo $?
0
[root@proxy opt]# [ -r /opt/abc ]      ##测试当前用户对abc是否有读权限
[root@proxy opt]# echo $?
0
[root@proxy opt]# [ -w /opt/abc ]      ##测试当前用户对abc是否有写权限
[root@proxy opt]# echo $?
0
[root@proxy opt]# [ -x /opt/abc ]     ##测试当前用户对abc是否有执行权限
[root@proxy opt]# echo $?
0
[root@proxy opt]# [ -d /opt/abc ]     ##测试abc是否存在,必须是目录
[root@proxy opt]# echo $?
0
[root@proxy opt]# touch 123     
[root@proxy opt]# chmod 000 123
[root@proxy opt]# ls -ld 123
---------- 1 root root 0 1月   3 14:20 123
[root@proxy opt]# [ -x /opt/123 ]     ##测试当前用户对123文件是否有执行权限
[root@proxy opt]# echo $?
1
[root@proxy opt]# [ -w /opt/123 ]    ##读和写权限对root用户无效
[root@proxy opt]# echo $?
0
[root@proxy opt]# [ -r /opt/123 ]
[root@proxy opt]# echo $?
0

if判断语句

  • 1.单分支
  • 当"条件成立" 是执行指令
  • 否则,不执行任何操作
    单分支结构:
 if   条件测试;then
      执行指令1
      执行指令2
      ......
 fi

单分支的执行流程
shell条件测试_第1张图片

  • 2.双分支
  • 语法特点
  • 当"条件成立"时执行指令1
  • 否则,执行指令2
    双分支结构:
if  条件测试1;then
    执行指令1
else
	执行指令2
fi	

双分支的执行流程
shell条件测试_第2张图片

  • 3.多分支
  • 相当于if语句嵌套
  • 针对多个条件分别执行不同的操作
    多分支结构:
if   条件测试1;then
	执行指令1
elif  条件测试2;then
	执行指令2
else
	执行指令3
fi

多分支的执行流程
shell条件测试_第3张图片

for循环

语法特点

  • 遍历/列表式循环
  • 根据变量的不同取值,重复执行指令
  • 有次数的重复执行某项任务
    **for循环结构 **
for   变量名  in  值1  值2  值3 ......  ##常规写法
do
	执行任务
done
--------------------------------------------------------------------------------
for   变量名  in  {1..100}  ##精简写法
do
	执行任务
done
--------------------------------------------------------------------------------
a=10
for   变量名  in  `seq $a`  ##支持变量的写法
do
	执行任务
done

for循环的执行流程
shell条件测试_第4张图片

利用for循环写一个ping的脚本

ping的工具选项:
-c 设置ping次数
-i 设置ping间隔时间,单位为秒
-W 设置失败后的反馈时间,单位为秒

[root@proxy opt]# vim  test11.sh
#!/bin/bash
#这是一个ping的测试脚本
x=0
y=0
read -p "请输入ip地址网段" ip
for i in {1..254}
do
    ping -c 3 -i 0.2 -W 1 192.168.$ip.$i &> /dev/null
    if [ $? -eq 0 ] ; then
        echo "Host 192.168.$ip.$i is 通了."
        let x++
    else
        echo "Host 192.168.$ip.$i is down."
        let y++
    fi
done
echo "有$x台通了,$y台没通"

while循环

语法特点

  • 条件式循环
  • 反复测试条件,只要成立就执行指令
  • 不限制循环的次数
    while循环结构
while 条件测试     ##条件满足即可执行后续任务
do
	执行任务
done
--------------------------------------------------------------------------------
while :     
do
	执行任务
done

while循环的执行流程
shell条件测试_第5张图片

利用while循环写一个猜数字脚本

#!/bin/bash
#这是一个简单的猜数字测试脚本
x=$[RANDOM%101]
while :
do
read -p "请输入(0-100)之间的数字:" a
if [ $x -eq $a ];then
        echo "猜对了"
exit
elif [ $x -gt $a ];then
        echo "猜小了"
else
        echo "猜大了"
fi
done
[root@proxy opt]# bash test12.sh   ##执行脚本,直到猜会了才退出
请输入(0-100)之间的数字:65
猜大了
请输入(0-100)之间的数字:60
猜大了
请输入(0-100)之间的数字:55
猜小了
请输入(0-100)之间的数字:59
猜大了
请输入(0-100)之间的数字:57
猜小了
请输入(0-100)之间的数字:58
猜对了

你可能感兴趣的:(笔记)