shell编程之条件语句(条件测试、if语句、case语句)(上)

简介: 要使Shell脚本程序具备一定的“智能”,面临的第一个问题就是如何区分不同的情况以确定执行何种操作。Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0时表示成功,否则(非0值)表示失败或异常。使用专门的测试工具——test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值为0表示条件成立)。使用test测试命令时,有以下两种形式:

要使Shell脚本程序具备一定的“智能”,面临的第一个问题就是如何区分不同的情况以确定执行何种操作。Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0时表示成功,否则(非0值)表示失败或异常。

使用专门的测试工具——test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值为0表示条件成立)。

使用test测试命令时,有以下两种形式:

格式一: test 条件表达式
 格式二: [ 条件表达式 ]
 #注意:每一项之间要有空格,格式二更常用
复制代码


条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成。

测试过程,实现评估布尔声明,以便用在条件性环境下进行执行:

  • 若为真,则状态码变量 $? 返回0
  • 若为假,则状态码变量 $? 返回非0


1 条件测试语句


1.1文件测试

文件测试格式

格式一: test 操作符 表达式
 格式二: [ 操作符 表达式 ]  
复制代码


常用的文件测试操作符:

操作符 作用
-d 测试文件是否为目录文件(Directory)
-f 测试文件是否为普通文件(File)
-e 测试目录或文件是否存在(Exist)。建议使用-e,-a可能不准确。
-a 测试目录或文件是否存在(Exist)
-r 测试当前用户是否有权限读取(Read)
-w 测试当前用户是否有权限写入(Write)
-x 测试当前用户是否有权限执行(eXcute)
-L 测试是否为符号链接(软链接文件)
-nt 判断文件A是否比文件B新
-ot 判断文件A是否比文件B旧
-ef 判断两个文件是否为同一文件。可用于硬链接,主要判断两个文件是否指向同一个inode。


属性测试补充:

操作符 作用
-s FILE 判断文件是否存在且非空
-t fd fd 指定文件描述符是否在某终端已经打开
-N FILE 文件自从上一次被读取之后是否被修改过
-O FILE 当前有效用户是否为文件属主
-G FILE 当前有效用户是否为文件属组


示例1:

[root@yuji ~]# test -d /etc/      //测试是否为目录
 [root@yuji ~]# echo $?
 0                                 //状态码返回0,表示为真,是目录
 [root@yuji ~]# [ -d /etc/ ]       //测试是否为目录
 [root@yuji ~]# echo $?
 0
 [root@yuji ~]# test -f /etc/sysconfig     //测试是否为普通文件
 [root@yuji ~]# echo $?
 1                                        //状态码返回1,表示为假,不是普通文件
 [root@yuji ~]# [ -f /etc/sysconfig ]     //测试是否为普通文件
 [root@yuji ~]# echo $?
 1
复制代码


网络异常,图片无法展示
|


示例2:

-e和-a都可以测试文件是否存在,但和 !(取反)连用时,-a可能不准确,建议使用-e

[root@yuji ~]# [ -e /etc/shadow ]     //测试文件是否存在
 [root@yuji ~]# echo $?
 0
 [root@yuji ~]# [ -a /etc/shadow ]     //测试文件是否存在
 [root@yuji ~]# echo $?
 0
 [root@yuji ~]# [ ! -a /etc/shadow ];echo $?     //测试文件是否不存在,判断结果有误
 0
 [root@yuji ~]# [ ! -e /etc/shadow ];echo $?     //测试文件是否不存在
 1
复制代码


网络异常,图片无法展示
|


示例3:

测试root用户对文件是否拥有读、写、执行权限。

发现root用户的读取和写入权限,不受文件的基本权限控制;但执行权限受文件基本权限控制。

[root@yuji ~]# ll /etc/shadow
 ----------. 1 root root 3792 3月  31 21:59 /etc/shadow
 [root@yuji ~]# [ -r /etc/shadow ]     //测试root用户对文件是否拥有读取权限
 [root@yuji ~]# echo $?
 0
 [root@yuji ~]# [ -w /etc/shadow ]     //测试root用户对文件是否拥有写入权限
 [root@yuji ~]# echo $?
 0
 [root@yuji ~]# [ -x /etc/shadow ]     //测试root用户对文件是否拥有执行权限
 [root@yuji ~]# echo $?
 1
复制代码


网络异常,图片无法展示
|


示例4:

测试软链接时,目录名称后面不要加"/",不然会被判断为目录文件。

[root@yuji /]# ls -dl /bin
 lrwxrwxrwx. 1 root root 7 3月   8 19:13 /bin -> usr/bin    //该文件为软链接文件
 [root@yuji /]# [ -L /bin ]        //测试是否为软链接,是
 [root@yuji /]# echo $?
 0
 [root@yuji /]# [ -L /bin/ ]       //测试是否为软链接,不是
 [root@yuji /]# echo $?
 1
 [root@yuji /]# ls -dl /bin/
 dr-xr-xr-x. 2 root root 49152 4月   5 02:15 /bin/      //该文件为目录文件
复制代码


网络异常,图片无法展示
|


1.2 整数测试

整数值比较:

[  整数变量1  操作符  整数变量2  ] 
 test 整数变量1  操作符  整数变量2
复制代码


操作符:

操作符 含义
-eq 等于(Equal)
-ne 不等于(Not Equal)
-gt 大于(Greater Than)
-lt 小于(Lesser Than)
-le 小于或等于(Lesser or Equal)
-ge 大于或等于(Greater or Equal)

示例1:

[root@yuji /]# [ 2 -lt 3 ]       //测试2是否小于3
 [root@yuji /]# echo $?
 0
 [root@yuji /]# a=5
 [root@yuji /]# b=6
 [root@yuji /]# [ $a -eq $b ]     //测试变量a是否等于变量b
 [root@yuji /]# echo $?
 1
复制代码


网络异常,图片无法展示
|


示例2:

查询当前目录下的文件数量是否大于10,如果大于,则进行提示。

[root@yuji ~]# ls | wc -l
 40
 [root@yuji ~]# test `ls |wc -l` -gt 10 && echo "文件数量大于10"
 文件数量大于10
复制代码


网络异常,图片无法展示
|


1.3 字符串测试

常用的测试操作符

  • =:字符串内容相同
  • !=:字符串内容不同,! 号表示相反的意思
  • -z:字符串内容为空
  • -n:字符是否存在

字符串比较,常用的四种格式:

[ "字符串1"  =  "字符串2"  ]   //测试字符串1和字符串2的内容是否相同
 [ "字符串1" !=  "字符串2”  ]   //测试字符串1和字符串2的内容是否不同
 [ -z "字符串" ]    //测试字符串是否为空,或者指定的变量是否为空值。(测试字符串的长度是否为零)
 [ -n "字符串" ]    //测试字符串是否存在,即是否不为空。(测试字符串的长度是否非零)
复制代码


示例1:


[root@yuji ~]# str1=aa
 [root@yuji ~]# str2=bb
 [root@yuji ~]# [ $str1 = $str2 ];echo $?    //测试变量1和变量2的值是否相同
 1
 [root@yuji ~]# [ $USER = root ];echo $?     //测试当前用户是否为root
 0
 [root@yuji ~]# [ $USER != root ];echo $?    //测试当前用户是否不为root
 1
 [root@yuji ~]# [ -z $HOME ];echo $?        //测试变量HOME是否为空值
 1
复制代码


网络异常,图片无法展示
|


示例2:

使用-z或-n测试变量时,变量需要加引号,避免有歧义而导致判断结果有误。

[root@yuji ~]# empty=              //设置一个空值变量
 [root@yuji ~]# echo $empty
 [root@yuji ~]# [ -z $empty ]       //测试变量是否为空值,为空
 [root@yuji ~]# echo $?
 0
 [root@yuji ~]# [ -n $empty ]       //变量没加引号,导致判断结果有误
 [root@yuji ~]# echo $?
 0
 [root@yuji ~]# [ -n "$empty" ]     //加了引号,判断结果正确
 [root@yuji ~]# echo $?
 1
复制代码


网络异常,图片无法展示
|


1.4 逻辑测试(短路运算)

逻辑测试用于连接多个测试条件,并返回整个表达式的值。 逻辑测试主要有"逻辑与","逻辑或","逻辑否"三种。

逻辑测试两种格式:

格式一:[  表达式1  ]  逻辑运算符  [  表达式2  ] ...
 #例:[表达式1] && [表达式2]  等同于  [表达式1 -a 表达式2]  等同于  [[表达式1 && 表达式2]]
 #例:[表达式1] || [表达式2]  等同于  [表达式1 -o 表达式2]  等同于  [[表达式1 || 表达式2]]
 格式二:命令1  逻辑运算符  命令2  ... 
复制代码


逻辑运算符:

  • -a或&& :逻辑与,“而且”的意思,全真才为真。
  • -o或|| :逻辑或,“或者”的意思,一真即为真。
  • ! :逻辑否。

网络异常,图片无法展示
|


1)短路与 &&

CMD1 && CMD2 
 全真才为真,一假即为假。      
 第一个CMD1结果为真 ,第二个CMD2必须要参与运算,才能得到最终的结果。
 第一个CMD1结果为假 ,总的结果必定为假,因此不需要执行CMD2。
 同时满足命令1 和命令2 的要求,才会返回正确。
复制代码


2)短路或 ||

CMD1 || CMD2
 一真即为真
 第一个CMD1结果为真,总的结果必定为真,因此不需要执行CMD2。
 第一个CMD1结果为假,第二个CMD2必须要参与运算,才能得到最终的结果。
复制代码


1.4.1 二元运算符

示例1:

[root@yuji ~]# [ 1 -lt 2 ] && [ 3 -eq 4 ]    //测试1是否小于2,同时3是否等于4
 [root@yuji ~]# echo $?
 1                                            //结果为假
 [root@yuji ~]# [ 1 -lt 2 ] || [ 3 -eq 4 ]    //测试1是否小于2,或者3是否等于4
 [root@yuji ~]# echo $?
 0                                            //结果为真
复制代码


网络异常,图片无法展示
|


示例2:

[表达式1] && [表达式2] 等同于 [表达式1 -a 表达式2] 等同于 [[表达式1 && 表达式2]]

[root@localhost ~]# a=5
 [root@localhost ~]# [ $a -ne 1 ]&&[ $a != 2 ]
 [root@localhost ~]# echo $?
 0
 [root@localhost ~]# [ $a -ne 1 -a  $a != 2 ]
 [root@localhost ~]# echo $?
 0
 [root@localhost ~]# [[ $a -ne 1 &&  $a != 2 ]]
 [root@localhost ~]# echo $?
 0
复制代码


网络异常,图片无法展示
|


1.4.2 三元运算符

1、java,C语言

  • 条件表达式?a:b
  • 当条件表达式为真时,取a值;当条件表达式为假时,取b值。

2、shell

  • [ 表达式 ] && a || b
  • 当表达式为真时,取a值;当表达式为假时,取b值。
[ 表达式 ]  && a           //相当于 if语句单分支结构
 [ 表达式 ]  && a || b      //相当于 if语句双分支结构
 [ 表达式 ]  || b           //相当于 if [表达式];else
复制代码


案例应用:查看指定主机是否在线。

1)方法一:使用三元运算符

[root@yuji ~]# vim ping001.sh       //使用三元运算符写脚本
 #!/bin/bash
 ping -c 3 -i 0.5 -w 3 $1 &>/dev/null && echo "$1 is up" || echo "$1 is down"
 [root@yuji ~]# bash ping001.sh 192.168.72.10      //执行脚本测试主机是否在线
 192.168.72.10 is up
 [root@yuji ~]# bash ping001.sh 192.168.72.22
 192.168.72.22 is down
复制代码


网络异常,图片无法展示
|


网络异常,图片无法展示
|


2)方法二:使用 if语句双分支结构

[root@yuji ~]# vim ping002.sh               //使用if语句写脚本
 #!/bin/bash
 ping -c 3 -i 0.5 -w 3 $1 &>/dev/null 
 if [ $? -eq 0 ]
 then
     echo "$1 is online" 
 else    
     echo "$1 is offline"
 fi
 [root@yuji ~]# bash ping002.sh 192.168.72.10      //执行脚本测试主机是否在线
 192.168.72.10 is online
 [root@yuji ~]# bash ping002.sh 192.168.72.22
 192.168.72.22 is offline
复制代码


网络异常,图片无法展示
|


网络异常,图片无法展示
|


小贴士:

ping命令:

  • -c,发送包的个数。
  • -i,发送的间隔时间。
  • -w(小写),多少秒后停止ping操作。
  • -W(大写),以毫秒为单位设置ping的超时时间 。


2 if 语句


2.1 if 单分支结构

单分支语句格式:

if  判断条件
 then  条件成立的分支代码
 fi                         //条件不成立直接结束
复制代码


网络异常,图片无法展示
|


相关文章
|
9天前
|
人工智能 自然语言处理 前端开发
CodeArena:在线 LLM 编程竞技场!用于测试不同开源 LLM 的编程能力,实时更新排行榜
CodeArena 是一个在线平台,用于测试和比较不同大型语言模型(LLM)的编程能力。通过实时显示多个 LLM 的代码生成过程和结果,帮助开发者选择适合的 LLM,并推动 LLM 技术的发展。
39 7
CodeArena:在线 LLM 编程竞技场!用于测试不同开源 LLM 的编程能力,实时更新排行榜
|
1月前
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
32 1
|
2月前
|
分布式计算 Hadoop Shell
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
80 4
|
3月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
55 2
|
2月前
|
安全 网络安全 数据安全/隐私保护
Python渗透测试之流量分析:流量嗅探工具编程
Python渗透测试之流量分析:流量嗅探工具编程
55 0
|
4月前
|
IDE Java 测试技术
揭秘Java高效编程:测试与调试实战策略,让你代码质量飞跃,职场竞争力飙升!
【8月更文挑战第30天】在软件开发中,测试与调试对确保代码质量至关重要。本文通过对比单元测试、集成测试、调试技巧及静态代码分析,探讨了多种实用的Java测试与调试策略。JUnit和Mockito分别用于单元测试与集成测试,有助于提前发现错误并提高代码可维护性;Eclipse和IntelliJ IDEA内置调试器则能快速定位问题;Checkstyle和PMD等工具则通过静态代码分析发现潜在问题。综合运用这些策略,可显著提升代码质量,为项目成功打下坚实基础。
68 2
|
4月前
|
存储 测试技术 数据库
Python接口自动化测试框架(练习篇)-- 函数编程(一)
本文通过实际的编程练习,讲解了面向过程编程的概念和应用,包括如何定义函数、处理文件读写以及实现用户注册功能,最终将这些过程封装成函数,体现了Python作为脚本语言的面向过程编程特性。
35 2
|
4月前
|
测试技术 Python
Python接口自动化测试框架(练习篇)-- 函数编程(二)
本文通过具体的编程练习,深入探讨了Python中的函数编程,包括如何定义函数、使用参数和返回值,以及函数式编程的技巧和应用,如使用lambda表达式和递归函数解决实际问题。
33 1
|
4月前
|
Shell
[shell]在curl测试的data参数中引用变量
[shell]在curl测试的data参数中引用变量
245 1
|
4月前
|
测试技术
一款功能完善的智能匹配1V1视频聊天App应该通过的测试CASE
文章列举了一系列针对1V1视频聊天App的测试用例,包括UI样式、权限请求、登录流程、匹配逻辑、消息处理、充值功能等多个方面的测试点,并标注了每个测试用例的执行状态,如通过(PASS)、失败(FAIL)或需要进一步处理(延期修改、待定、方案再定等)。
73 0