15、shell条件测试

RHCE板块

欢迎来到我的博客,这里是Linux板块,配合之前RHCSA进阶,希望我的博客可以帮助到您,感谢您的阅读,有什么问题还希望一起探讨交流,感谢各位的支持,感谢!

  1. 使用Linux搭建一个简单的论坛
  2. RHCE——一、安装部署及例行性工作
  3. RHCE——二、时间服务器
  4. RHCE——三、远程连接服务器
  5. RHCE——四、Web服务器(理论篇
  6. RHCE——五、Web服务器及内网穿透(实验篇
  7. RHCE——六、基于https协议的静态网站
  8. RHCE——七、搭建云存储器
  9. RHCE——八、DNS域名解析服务器
  10. RHCE——九、SELinux
  11. RHCE——十、防火墙、iptables、firewalld
  12. RHCE——十一、NFS服务器
  13. RHCE——十二、Mysql服务
  14. RHCE——十三、Shell自动化运维编程基础
  15. RHCE——十四、变量和引用
  16. RHCE——十五、shell条件测试
  17. RHCE——十六、流程控制之条件判断、循环
  18. RHCE——十七、文本搜索工具-grep、正则表达式
  19. RHCE——十八、shell编程之sed
  20. RHCE——十九、shell编程之awk
  21. RHCE——二十、Ansible及安装与配置
  22. RHCE——二十一、Ansible模块

一、用途

  • 为了能够正确处理Shell程序运行过程中遇到的各种情况,Linux Shell提供了一组测试运算符。
  • 通过这些运算符,Shell程序能够判断某种或者几个条件是否成立。
  • 条件测试在各种流程控制语句,例如判断语句和循环语句中发挥了重要的作用,所以了解和掌握这些条件测试是非常重要的

二、基本语法

1、格式

格式1: test  -参数  条件表达式
格式2: [  条件表达式  ]     # 注意:[]的左右要有空格
格式3: [[  条件表达式  ]]   # 注意:[]的左右要有空格
格式4: ((条件表达式))
  • test单独使用,判断条件为真,echo $?返回0,假返回1
  • test与[ ]等价
  • [[ ]] 是扩展命令,可以使用通配符(?*)等进行模式匹配,&& || > < 等操作符可以直接应用于双中括号中,但不能用于单中括号中
  • (()) 一般用于if语句里,两端不需要有空格,测试对象为整数

2、示例

# test 单独使用,必须配合状态码测试,0表示成立,1为不成立
[root@server ~]# test  -f  /etc/passwd
[root@server ~]# echo  $?
0
[root@server ~]# test  -f  /a1.txt
[root@server ~]# echo  $?
1

# test配置自编逻辑表示(成立为1,不成立为0)
[root@server ~]# test -f /etc/hosts  &&  echo 1 || echo 0
1
[root@server ~]# test -f /etc/a1.txt  &&  echo 1 || echo 0
0
# [ ] 等价于 test
[root@server ~]# [ -f /etc/passwd  ]
[root@server ~]# echo  $?
0
[root@server ~]# [ -f /etc/a1.txt  ]
[root@server ~]# echo  $?
1 
[root@server ~]# [-f /etc/passwd]   # []中需要加空格
bash: [-f: command not found...
[root@server ~]# [ -f /etc/passwd ] && echo 1 || echo 0
1
[root@server ~]# [ -f /etc/a1.txt ] && echo 1 || echo 0
0

在这里插入图片描述

[root@server ~]# [[ 3>2 || 1>2  ]]  #  运算符需要加空格
-bash: 条件命令中有未预期的符号 284
-bash: “3>”附近有语法错误
[root@server ~]# [[ 3 > 2 || 1 > 2  ]]
[root@server ~]# echo  $?
0
[root@server ~]# [[ 3 > 2 || 1 > 2  ]]  && echo yes || echo no
yes
[root@server ~]# [[ 3 > 2 && 1 > 2  ]]  && echo yes || echo no
no
[root@server ~]# ((3>5))  && echo  1  || echo 0
0
[root@server ~]# ((3<5))  && echo  1  || echo 0
1
[root@server ~]# ((-f /etc/passwd))  && echo  1  || echo 0  # 不支持文件测试
-bash: ((: -f /etc/passwd:除以 0 (错误符号是 "etc/passwd")
0
[root@server ~]# ((9.5!=0))  && echo  1  || echo 0  # 不支持小数测试
-bash: ((: 9.5!=0:语法错误: 无效的算术运算符 (错误符号是 ".5!=0")
0

三、文件测试

1、参数

参数作用
-b 文件名检测文件是否是块设备文件,是返回 true
-c 文件名是否是字符设备文件
-d 文件名是否是目录
-f 文件名是否是普通文件(既不是目录,也不是设备文件)
-S 文件名是否为socket文件
-P 文件名是否为管道符文件
-L 文件名是否为链接文件
-u 文件名是否有suid的权限
-s 文件名是否为空(文件大小是否大于0),不为空返回 true
-e 文件名检测文件(包括目录)是否存在,如果是,则返回 true
-r 文件名检测文件是否可读,如果是,则返回 true。
-w 文件名检测文件是否可写,如果是,则返回 true
-x 文件名检测文件是否可执行,如果是,则返回 true
f1 -nt f2文件f1比文件f2新则为真(根据文件修改时间计算)
f1 -ot f2文件f1比文件f2旧则为真(根据文件修改时间计算)

2、示例

[root@server ~]# [ -d /root ] && echo yes || echo no  
yes
[root@server ~]# [ -b /nvme0n1 ] && echo yes || echo no  
no
[root@server ~]# [ -b /dev/nvme0n1 ] && echo yes || echo no  
yes
[root@server ~]# [ -L  /dev/cdrom ] && echo yes || echo no  
yes
[root@server ~]# test  -e  /etc/file1  && echo  yes || echo no
no
[root@server ~]# touch  /etc/file1
[root@server ~]# test  -e  /etc/file1  && echo  yes || echo no
yes
[root@server ~]# [[ -r  /etc/sr0  ]]  && echo  1  || echo 0
0
[root@server ~]# [[ -r  /dev/sr0  ]]  && echo  1  || echo 0
1
[root@server ~]# (( -r  /dev/sr0 ))  && echo  1  || echo 0
-bash: ((: -r  /dev/sr0 :除以 0 (错误符号是 "dev/sr0 ")
0
# 编写脚本,测试在根目录下文件是否存在,文件名从键盘输入,若不存在则创建
[root@server ~]# vim  test1.sh

#!/bin/bash

read  -p "请输入文件名称: "  filename

if  test -e /$filename
then
        echo  "$filename exists and it is a normal file"
else    
        echo  "$filename doesn't exit!!"
        echo  "create  file  $filename automatically"
        touch  /$filename
fi      

[root@server ~]# bash test1.sh 
请输入文件名称: mnt    
mnt exists and it is a normal file
[root@server ~]# ls /
afs  bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@server ~]# bash test1.sh 
请输入文件名称: a1.txt
a1.txt doesn't exit!!
create  file  a1.txt automatically
[root@server ~]# ls  /
a1.txt  afs  bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

在这里插入图片描述

# 使用位置变量处理
[root@server ~]# vim  test1.sh
#!/bin/bash

filename=$1   # 接收位置变量

if  test -e /$filename
then
        echo  "$filename exists and it is a normal file"
else
        echo  "$filename doesn't exit!!"
        echo  "create  file  $filename automatically"
        touch  /$filename
fi

[root@server ~]# bash test1.sh mnt       # 注意:执行时文件名作为位置变量参数
mnt exists and it is a normal file
[root@server ~]# bash test1.sh a2.txt
a2.txt doesn't exit!!
create  file  a2.txt automatically

在这里插入图片描述

# 注意:使用find检测文件注意状态码

四、整数测试

1、作用

  • 用于比较两个数值的大小关系,操作的对象是数值

2、操作符

image-20230201111619255

3、示例

[root@server ~]# [ 5 -gt 3 ]  &&  echo  1  || echo 0
1
[root@server ~]# [ 5 >  3 ]  &&  echo  1  || echo 0
1
[root@server ~]# [ 5>3 ]  &&  echo  1  || echo 0
0
[root@server ~]# test  2  -lt 1  && echo 1  || echo 0  
0
[root@server ~]# ((5>3))  && echo  1  || echo 0
1

在这里插入图片描述

# 知识扩展
# =~ :检查左侧内容是否匹配右侧的正则表达式
[root@server ~]# n1=123   # 匹配n1存储的内容是否全为数字
[root@server ~]# [[ $n1 =~ ^[0-9]+$  ]]  && echo 1 ||  echo 0
1
[root@server ~]# n1="china"
[root@server ~]# [[ $n1 =~ ^[0-9]+$  ]]  && echo 1 ||  echo 0
0
[root@server ~]# n1=123abc
[root@server ~]# [[ $n1 =~ ^[0-9]+$  ]]  && echo 1 ||  echo 0
0

在这里插入图片描述

# 编写表达式,测试系统用户少于50个则输出相关信息
[root@server ~]# [ $(cat  /etc/passwd | wc -l) -lt 50  ] && echo "用户数小于50"  || echo "用户数大于50"
用户数小于50
[root@server ~]# cat  /etc/passwd  |  wc -l
37

4、案例分析

  • 例1:判断当前的已登录的账户数,超过5个则输出提示信息
[root@server ~]# num=$(who | cut -d " " -f1 | sort -u | wc -l)

[root@server ~]# [ $num -gt 5 ] && echo "账户过多" || echo  "实际账户数:" $num
实际账户数: 1

# who :查看账户信息
# cut -d  " "  -f1  : 以空格作为列间隔符,截取第1列
# sort -u :去重后排序
# wc :-l :统计行数
  • 例2:如果/var/log/messages 文件行数大于50行,则显示提示信息
[root@server ~]# (($(cat  /var/log/messages | wc -l)>50))  &&  echo  "好大一个文件"  || echo  "还能接受"
好大一个文件
  • 例3:编写一个脚本mkfs.sh,功能:显示root账户下的文件信息,之后建立一个aa目录,在aa目录中新建一个文件bb.txt,并修改为可执行的权限
[root@server ~]# vim  mkfs.sh
#!/bin/bash
ls  /root
mkdir  /root/aa
touch  /root/aa/bb.txt
chmod a+x /root/aa/bb.txt    #(a表示all,所有人)
[root@server ~]# bash mkfs.sh 

在这里插入图片描述

  • 例4:编写脚本mkd.sh,从键盘输入一个目录名,判断是否存在,不存在则创建
[root@server ~]# vim  mkd.sh
#!/bin/bash
cd  /
ls
read -p "请输入一个目录名称: " dir
[ -d $dir ] && ls -ld $dir  || ( echo  "目录不存在,开始新建目录." ;  mkdir  $dir ;  ls  -ld  $dir)
[root@server ~]# bash  mkd.sh

在这里插入图片描述
在这里插入图片描述

  • 例5:编写脚本sum1.sh,从键盘读入2个整数存储到x,y中,计算和值后输出
#!/bin/bash
read -p "请输入x的值: " x
read -p "请输入y的值: " y
if  [ -n $x -a -n $y ]   # 判断是否为空
then
        if [[ $x =~  ^[0-9]+$ ]]  &&  [[ $y =~ ^[0-9]+$ ]]  # 判断是否为数字
        then
                sum=$[x+y]
                echo "$x+$y=$sum"
        else
                echo  "请输入数字."
        fi
else
        echo "请输入有效数字."
fi

在这里插入图片描述
在这里插入图片描述

  • 例6:编写脚本user1.sh,显示所有账户,选择一个账户输入,若id为0则表示管理员,否则表示其他账户
[root@server ~]# vim  user1.sh
#!/bin/bash
cat /etc/passwd  |  cut -d ":" -f1 | sort -u
read -p "请输入账户名:" us
[ $(id -u $us)  -eq 0 ] && echo  "此账户为管理员" || echo "此账户为其他账户"
[root@server ~]# bash user1.sh 

在这里插入图片描述
在这里插入图片描述

  • 例7:编写脚本line1.sh ,统计/etc/sos/sos.conf文件中的空白行(^$),若有空白行则显示行数,否则输出提示信息
[root@server ~]# vim  line1.sh
#!/bin/bash
num=$( grep ^$ /etc/sos/sos.conf | wc -l )
if (($num>0))  #  [ $numn -gt 0  ]
then
        echo "/etc/sos/sos.conf 包含空白行,行数为: $num行"
        grep  -n  ^$  /etc/sos/sos.conf
else
        echo "/etc/sos/sos.conf 文件无空白行"
fi

在这里插入图片描述
在这里插入图片描述

# 修改为任意文件的测试
[root@server ~]# vim  line1.sh
#!/bin/bash
read -p "请输入需要统计的文件名: "  filename
num=$( grep ^$  $filename  | wc -l )
if (($num>0))  #  [ $numn -gt 0  ]
then
        echo "$filename  包含空白行,行数为: $num行"
        grep  -n  ^$  $filename
else
        echo "$filename  文件无空白行"
fi

在这里插入图片描述
在这里插入图片描述

五、逻辑操作符

1、符号

image-20230201113034549

2、例

[root@server ~]# [ -f /etc/passwd -a -f /etc/services ] && echo 1 || echo 0
1
[root@server ~]# [ -f /etc/hosts -o -d /etc/services ] && echo  1 || echo 0
1
[root@server ~]# ((5<10 && 5>2))  && echo y || echo n
y
[root@server ~]# ((2<5<10))  && echo y || echo n
y
[root@server ~]# ((2<5<1))  && echo y || echo n
n
[root@server ~]# ((6<5<10))  && echo y || echo n
y
[root@server ~]# ((2<5<-1))  && echo y || echo n
n

在这里插入图片描述

六、命令分隔符

cmd1;cmd2     以独立的进程依次执行cmd1和cmd2
(cmd1;cmd2)   在同一进程中依次执行cmd1和cmd2
cmd1&cmd2     cmd1和cmd2同时执行,分属于不同的进程
cmd1&&cmd2    当cmd1为真时,则执行cmd2
cmd1||cmd2    当cmd1不为真时,则执行cmd2
cmd&          后台执行
# 若账户fox10不存在,则添加账户
[root@server ~]# id fox10  &>  /dev/null  &&  echo  "fox10已存在"  ||  useradd  fox10
# &>  /dev/null 表示将左侧命令执行的正确和错误输出到“黑洞”即不显示到屏幕(不管成功与否,都将信息写进黑洞中)
  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值