linux shell编程之条件语句(二)

目录

一. 条件测试操作

1. 文件测试

2. 整数值比较 

3. 字符串比较 

4. 逻辑测试

 二. if 条件语句

1. if 语句的结构

(1) 单分支 if 语句

(2) 双分支 if 语句 

(3) 多分支 if 语句

2. if 语句应用示例

(1) 单分支 if 语句应用

(2) 双分支 if 语句应用

(3) 多分支 if 语句应用

三. case 分支语句

1. case 语句的结构 

2. case 语句应用示例

(1) 检查用户输入的字符类型

(2) 编写系统服务脚本


Shell编程作为 Linux 系统管理的重要组成部分,其强大的脚本处理能力为自动化任务提供了极大便利。在 Shell脚本编写中,条件语句是不可或缺的逻辑控制结构,它们使得脚本能够根据不同的条件执行相应的操作,从而实现智能化和高效化。

一. 条件测试操作

要使 shell 脚本程序具备一定的“智能”,面临的第一个问题就是如何区分不同的情况以确定执行何种操作。

如当磁盘使用率超过 95%时,发送告警信息;当备份目录不存在时,能够自动创建;当源码编译程序时,若配置失败则不再继续安装等。

Shel1l环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为 0 时表示成功,否则(非 0 值)表示失败或异常。

使用 test 测试命令时,包括以下两种形式

test  条件表达式
[条件表达式]

两种方式的作用完全相同,但通常后一种形式更为常用,也更贴近编程习惯。需要注意的是,方括号“[”或“]”与条件表达式之间需要至少一个空格进行分隔。

根据需要测试的条件类别不同,条件表达式也不同。比较常用的条件操作包括文件测试、整数值比较、字符串比较,以及针对多个条件的逻辑测试

1. 文件测试

文件测试指的是根据给定的路径名称,判断对应的是文件还是目录,或者判断文件是否可读、可写、可执行等。文件测试的常见操作选项

-d测试是否为目录(Directory)
-e测试目录或文件是否存在(Exist)
-f测试是否为文件(File)
-r测试当前用户是否有权限读取(Read)
-w测试当前用户是否有权限写入(write)
-x测试是否设置有可执行(Excute)权限

执行条件测试操作以后,通过预定义变量$?可以获得测试命令的返回状态值,从而判断该条件是否成立 

如果返回值$?为 0,表示存在此目录,否则表示不存在或者虽然存在但不是目录。

 若测试的条件不成立,则测试操作的返回值将不为 0(通常为 1)。

 

通过査看变量$?的值可以判断前一步的条件测试结果,但是操作比较烦琐,输出结果也并不是很直观。为了更直观地査看测试结果,可以结合命令分隔符“&&”和 echo 命令一起使用,当条件成立时直接输出“YES”。

“&&”符号表示“而且”的关系,只有当前面的命令执行成功后才会执行后面的命令。否则后面的命令将会被忽略。

无输出表示该目录不存在

输出"YES"表示该目录存在

2. 整数值比较 

整数值比较指的是根据给定的两个整数值,判断第一个数与第二个数的关系,如是否大于、等于、小于第二个数。整数值比较的常用操作选项如下,使用时将操作选项放在要比较的两个整数之间。

-eq: 第一个数等于(Equal)第二个数。
-ne: 第一个数不等于(Not Equal)第二个数。
-gt: 第一个数大于(Greater Than)第二个数。
-lt: 第一个数小于(Lesser Than)第二个数。
-le: 第一个数小于或等于(Lesser or Equal)第二个数。
-ge: 第一个数大于或等于(Greater or Equal)第二个数。

整数值比较在 shell 脚本编写中的应用较多。来判断已登录用户数量、开启进程数、磁盘使用率是否超标,以及软件版本号是否符合要求等。实际使用时,往往会通过变量引用、命令替换等方式来获取一个数值。

若要判断当前已登录的用户数,当超过二个时输出“Too many.”,已登录用户数可通过“who | wc -l”命令获得,可以执行以下操作

已知当前登录数为5 当当前用户登录超过2个时显示Too many

若要判断物理内存(Mem)当前的磁盘缓存(buff/cache)大小,当低于 1024MB 时输出具体数值,“free -m”命令表示以 MB 为单位输出内存信息,提取的空闲内存数值通过命令替换赋值给变量 FreeCC,可以执行以下操作。

3. 字符串比较 

字符串比较通常用来检査用户输入、系统环境等是否满足条件,在提供交互式操作的 shell 脚本中,也可用来判断用户输入的位置参数是否符合要求。字符串比较的常用操作选项

=:第一个字符串与第二个字符串相同。
!=:第一个字符串与第二个字符串不相同,其中“!”符号表示取反
-z:检查字符串是否为空(Zero),对于未定义或赋予空值的变量将视为空串。

若要判断当前系统的语言环境,当发现不是“en.us”时输出提示信息“Not en.us”,可以执行以下操作

查看语言环境 测试结果不等于 

在 Shell 脚本应用中,经常需要用户输入“yes”或“no”来确认某个任务。以下操作展示了确认交互的简单过程,当然,实际使用时还会根据变量“ACK”的取值分别执行进一步的操作。

4. 逻辑测试

逻辑测试指的是判断两个或多个条件之间的依赖关系。当系统任务取决于多个不同的条件时,根据这些条件是否同时成立或者只要有其中一个成立等情况,需要有一个测试的过程。使用时放在不同的测试语句或命令之间。

&&逻辑与,表示“而且”,只有当前后两个条件都成立时,整个测试命令的返回值才为 0(结果成立)。使用 test 命令测试时,“&&”可改为“-a”
| |逻辑或,表示“或者”,只要前后两个条件中有一个成立,整个测试命令的返回值即为 0(结果成立)。使用 test 命令测试时,“||”可改为“-o”
逻辑否,表示“不”,只有当指定的条件不成立时,整个测试命令的返回值才为 0(结果成立)

“&&”和“||”通常也用于间隔不同的命令操作,其作用是相似的。

若要判断当前 Linux 系统的内核版本是否大于 3.4,内核版本号通过 uname 和 awk 命令获得。,可以执行以下操作。

查看内核版本号  主办版号  次版本号  是否符合要求        不符合不会给任何信息

 二. if 条件语句

使用专用的 if 条件语句,可以更好地整理脚本结构,使得层次分明,清晰易懂。

1. if 语句的结构

在 shell 脚本应用中,if 语句是最为常用的一种流程控制方式,用来根据特定的条件测试结果,分别执行不同的操作(如果.…那么.…)。根据不同的复杂程度,if 语句的选择结构可以分为三种基本类型,适用于不同的应用场合。

(1) 单分支 if 语句

if 语句的“分支”指的是不同测试结果所对应的执行语句(一条或多条)。对于单分支的选择结构,只有在“条件成立”时才会执行相应的代码,否则不执行任何操作。

语法格式

if 条件测试操作
then命令序列
fi

条件测试操作既可以是“[条件表达式]"语句,也可以是其他可执行的命令语句;命令序列指的是一条或多条可执行的命令行,也包括嵌套使用的 if 语句或其他流程控制语句。

单分支 if 语句的执行流程:首先判断条件测试操作的结果,如果返回值为 0,表示条件成立,执行then 后面的命令序列,一直到遇见 fi 结束判断为止,继续执行其他脚本代码;如果返回值不为 0,则忽略 then 后面的命令序列,直接跳至 fi 行以后执行其他脚本代码

(2) 双分支 if 语句 

对于双分支的选择结构,要求针对“条件成立”“条件不成立”两种情况分别执行不同的操作。

语法格式

if 条件测试操作
then命令序列 1
else命令序列 2
fi

双分支 if 语句的执行流程:首先判断条件测试操作的结果,如果条件成立,则执行 then 后面的命令序列 1,忽略 else 及后面的命令序列 2,直到遇见 fi 结束判断;如果条件不成立,则忽略 then 及后面的命令序列 1,直接跳至 else 后面的命令序列 2 并执行,直到遇见 fi 结束判断

(3) 多分支 if 语句

由于 if 语句可以根据测试结果的成立、不成立分别执行操作,所以能够嵌套使用,进行多次判断。

语法格式

if 条件测试操作 1
then命令序列 1
elif 条件测试操作 2
then命令序列 2
else命令序列 3
fi

语句结构中只嵌套了一个 elif 语句作为示例,实际上可以嵌套多个。if 语句的嵌套在编写Shel1 脚本时并不常用,因为多重嵌套容易使程序结构变得复杂。当确实需要使用多分支的程序结构时,可以采用 case 语句更加方便

多分支 if 语句的执行流程:首先判断条件测试操作1 的结果,如果条件 1 成立,则执行命令序列1,然后跳至 fi 结束判断;如果条件 1 不成立,则继续判断条件测试操作 2 的结果,如果条件 2 成立,则执行命令序列 2,然后跳至 fi 结束判断……如果所有的条件都不满足,则执行 else 后面的命令序列n,直到遇见 fi 结束判断

2. if 语句应用示例

(1) 单分支 if 语句应用

多 Linux 用户习惯上将光盘设备挂载到/media/cdrom 目录下,但 Linux 系统默认并没有建立此目录。若需要在 shel1 脚本中执行挂载光盘的操作,建议先判断挂载点目录是否存在,若不存在则新建此目录。

 

有些特权命令操作要求以 root用户执行,如果当前用户不是 root,那么再执行这些命令就没有必要(肯定会失败)。针对这种情况,在脚本中可以先判断当前用户是不是root,如果不是则报错并执行“exit 1”命令退出脚本(1 表示退出后的返回状态值),而不再执行其他代码。

                

 

 

当 root 用户执行 chkifroot.sh 脚本时,由于“非 root 用户”的条件不成立,所以 if 语句不执行任何操作,正常执行 fi 之后的脚本代码。 

[root@localhost ~l# /opt/aaa.sh
….//省略部分内容
Device Boot Start End Blocks Id System
/dev/sda1 *2048 40894463 20446208 83 Linux
/dev/sda2 40894464 41943039 524288 82 Linux swap / Solaris

(2) 双分支 if 语句应用

双分支 if 语句只是在单分支的基础上针对“条件不成立”的情况执行另一种操作,而不是“坐视不管”地不执行任何操作。

若要编写一个连通性测试脚本 bbb.sh,通过位置参数$1 提供目标主机地址,然后根据 ping 检测结果给出相应的提示,可以参考以下操作过程

 

脚本代码中,为了提高 ping 命令的测试效率,使用了“-c’”“-i”“-w”选项,分别指定只发送三个测试包、间隔 0.2 秒、超时 3 秒。另外,通过“&>/dev/null”屏蔽了 ping 命令执行过程的输出信息。

通过 she11 脚本检査 vsftpd 服务是否运行,如果已经运行则列出其监听地址、PID 号,否则输出提示“警告:vsftpd 服务不可用!”。其中,pgrep 命令的“-x”选项表示查找时使用精确匹配

 

 

(3) 多分支 if 语句应用

与单分支、双分支 if 语句相比,多分支 if 语句的结构能够根据多个互斥的条件分别执行不同的操作,实际上等同于嵌套使用的 if 语句

若要编写一个成绩分档的脚本 ddd.sh,根据输入的考试分数不同来区分优秀、合格、不合格三挡,可以参考以下操作过程

 

三. case 分支语句

1. case 语句的结构 

case 语句主要适用于以下情况:某个变量存在多种取值,需要对其中的每一种取值分别执行不同的命令序列。这种情况与多分支的 if 语句非常相似,只不过 if 语句需要判断多个不同的条件,而 case语句只是判断一个变量的不同取值。

语法结构

case 变量值 in
模式 1)命令序列 1;;
模式 2)命令序列 2
;;...
* )默认命令序列
esac

在上述语句结构中,关键字 case 后面跟的是“变量值”,即“$变量名”。整个分支结构包括在case..esac 之间,中间的模式 1、模式 2、…、*对应为变量的不同取值(程序期望的取值),其中*作为通配符,可匹配任意值。

case语句的执行流程:首先使用“变量值”与模式1进行比较,若取值相同则执行模式1 后的命令序列,直到遇见双分号“;;”后跳转至 esac,表示结束分支;若与模式 1 不相匹配,则继续与模式 2进行比较,若取值相同则执行模式 2后的命令序列,直到遇见双分号“;;”后跳转至 esac,表示结束分支.…依此类推,若找不到任何匹配的值,则执行默认模式“*)”后的命令序列,直到遇见 esac 后结束分支

使用 case 分支语句时,有几个值得注意的特点

case 行尾必须为单词“in”,每一模式必须以右括号“)”结束。
双分号“;;”表示命令序列的结束。
模式字符串中,可以用方括号表示一个连续的范围,如“[0-9]”;还可以用竖杠符号“|”表示或,如“A|B”
最后的“*)”表示默认模式,其中的*相当于通配符。

2. case 语句应用示例

(1) 检查用户输入的字符类型

提示用户从键盘输入一个字符,通过 case 语句判断该字符是否为字母、数字或者其他控制字符,并给出相应的提示信息。

 

(2) 编写系统服务脚本

编写一个名为 hhh.sh的系统服务脚本,通过位置变量$1 指定的 start、stop、restart、status控制参数,分别用来启动、停止、重启 sleep 进程,以及査看 sleep 进程的状态。其中,命令 sleep 用来暂停指定秒数的时间,这里仅用做测试,在实际运维工作中应将 sleep 改为相应后台服务的控制命令序列。

 

在 Linux 系统中,源码软件包编译安装后提供的服务控制脚本使用了 case 分支语句;也有一些源码包没有提供服务控制脚本,编译安装后可参照上例自行编写服务控制脚本。平时控制各种系统服务时,供的 start、stop、restart 等位置参数,正是由 case 语句结构来识别并完成相应操作的。
若要将 hhh.sh 服务交给 systemd 来管理,还需要在/lib/systemd/system 目录下添加相应的myprog.service 配置文件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/76425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

榕壹云在线商城系统:基于THinkPHP+ Mysql+UniApp全端适配、高效部署的电商解决方案

项目背景:解决多端电商开发的痛点 随着移动互联网的普及和用户购物习惯的碎片化,传统电商系统面临以下挑战: 1. 多平台适配成本高:需要同时开发App、小程序、H5等多端应用,重复开发导致资源浪费。 2. 技术依赖第三方…

神经动力学系统与计算及AI拓展

大脑,一个蕴藏在我们颅骨之内的宇宙,以活动脉动,如同由电信号和化学信号编织而成的交响乐,精巧地协调着思想、情感和行为。但是,这种复杂的神经元舞蹈是如何产生我们丰富多彩的精神生活的呢?这正是神经动力…

K8s常用基础管理命令(一)

基础管理命令 基础命令kubectl get命令kubectl create命令kubectl apply命令kubectl delete命令kubectl describe命令kubectl explain命令kubectl run命令kubectl cp命令kubectl edit命令kubectl logs命令kubectl exec命令kubectl port-forward命令kubectl patch命令 集群管理命…

本地化部署DeepSeek-R1蒸馏大模型:基于飞桨PaddleNLP 3.0的实战指南

目录 一、飞桨框架3.0:大模型推理新范式的开启1.1 自动并行机制革新:解放多卡推理1.2 推理-训练统一设计:一套代码全流程复用 二、本地部署DeepSeek-R1-Distill-Llama-8B的实战流程2.1 机器环境说明2.2 模型与推理脚本准备2.3 启动 Docker 容…

单片机方案开发 代写程序/烧录芯片 九齐/应广等 电动玩具 小家电 语音开发

在电子产品设计中,单片机(MCU)无疑是最重要的组成部分之一。无论是消费电子、智能家居、工业控制,还是可穿戴设备,小家电等,单片机的应用无处不在。 单片机,简而言之,就是将计算机…

【位运算】两整数之和

文章目录 371. 两整数之和解题思路:位运算 371. 两整数之和 371. 两整数之和 ​ 给你两个整数 a 和 b ,不使用 运算符 和 - ,计算并返回两整数之和。 示例 1: 输入:a 1, b 2 输出:3示例 2&#xff1…

使用Python从零实现一个端到端多模态 Transformer大模型

嘿,各位!今天咱们要来一场超级酷炫的多模态 Transformer 冒险之旅!想象一下,让一个模型既能看懂图片,又能理解文字,然后还能生成有趣的回答。听起来是不是很像超级英雄的超能力?别急&#xff0c…

新闻推荐系统(springboot+vue+mysql)含万字文档+运行说明文档

新闻推荐系统(springbootvuemysql)含万字文档运行说明文档 该系统是一个新闻推荐系统,分为管理员和用户两个角色。管理员模块包括个人中心、用户管理、排行榜管理、新闻管理、我的收藏管理和系统管理等功能。管理员可以通过这些功能进行用户信息管理、查看和编辑用…

游戏引擎学习第218天

构建并运行,注意一下在调试系统关闭前人物的移动速度 现在我准备开始构建项目。如果我没记错的话,我们之前关闭了调试系统,主要是为了避免大家在运行过程中遇到问题。现在调试系统没有开启,一切运行得很顺利,看到那个…

基于混合编码器和边缘引导的拉普拉斯金字塔网络用于遥感变化检测

Laplacian Pyramid Network With HybridEncoder and Edge Guidance for RemoteSensing Change Detection 0、摘要 遥感变化检测(CD)是观测和分析动态土地覆盖变化的一项关键任务。许多基于深度学习的CD方法表现出强大的性能,但它们的有效性…

Go语言从零构建SQL数据库(6) - sql解析器(番外)- *号的处理

番外:处理SQL通配符查询 在SQL中,SELECT * FROM table是最基础的查询之一,星号(*)是一个通配符,表示"选择所有列"。虽然通配符查询看起来简单,但在解析器中需要特殊处理。下面详细介…

浅析Centos7安装Oracle12数据库

Linux下的Oracle数据库实在是太难安装了,事贼多,我都怀疑能安装成功是不是运气的成分更高一些。这里操作系统是Centos7,Oracle版本是Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production。 Oracle下载链接: https…

02-redis-源码下载

1、进入到官网 redis官网地址https://redis.io/ 2 进入到download页面 官网页面往最底下滑动,找到如下页面 点击【download】跳转如下页面,直接访问:【https://redis.io/downloads/#stack】到如下页面 ​ 3 找到对应版本的源码 https…

2024年博客之星的省域空间分布展示-以全网Top300为例

目录 前言 一、2024博客之星 1、所有排名数据 2、空间属性管理 二、数据抓取与处理 1、相关业务表的设计 2、数据抓取处理 3、空间查询分析实践 三、数据成果挖掘 1、省域分布解读 2、技术开发活跃 四、总结 前言 2024年博客之星的评选活动已经过去了一个月&#xf…

接口请求控制工具

接口请求控制工具 功能说明代理转发安全控制访问控制错误处理配置管理日志管理 技术栈快速开始环境要求配置说明启动服务 工具源码 功能说明 代理转发 支持多路由配置支持静态资源代理灵活的路由规则配置支持请求转发和响应处理支持负载均衡 支持多目标服务器配置提供多种负载…

Linux: 进程认识(组织进程)

进程认识 (一)冯诺依曼体系结构1.概念从数据流向上理解冯诺依曼 (二)操作系统(OS)1.概念2.设计目的3. 如何理解操作系统的 "管理"4.操作系统调用接口 (三) 进程1.概念2.描述进程-PCB3.如何对PCB进行管理? &a…

回文日期1

#include <iostream> using namespace std;bool isLeap(int y){return (y%40&&y%100!0)||(y%4000); }bool check(int year,int month,int day){//判断是否为合法日期if(month>12||month0) return false;if(day>31) return false;if(month2){if(isLeap(year…

安宝特案例 | 某户外机房制造企业应用AR+作业流,规范制造过程,记录施工节点,保障交付质量

行业特点&#xff1a;产品客制化、依赖人工&#xff0c;工程量大、细节多&#xff0c;验收困难 户外通讯机房无疑是现代工业社会的“信息心脏”&#xff0c;承载着信息交换、传输与处理的重任。建设一座质量过关的户外通讯机房是保障通信稳定运行的基石。 通常建设一个户外通信…

deepseek热度已过?

DeepSeek的热度并没有消退&#xff0c;以下是具体表现&#xff1a; 用户使用量和下载量方面 • 日活跃用户量增长&#xff1a;DeepSeek已经成为目前最快突破3000万日活跃用户量的应用程序。 • 应用商店下载量&#xff1a;1月26日&#xff0c;DeepSeek最新推出的AI聊天机器人…

蓝桥杯单片机刷题——通过按键触发串口传输电压值

设计要求 通过内部ADC完成电位器RB2的输出电压检测&#xff0c;并显示在数码管上&#xff1b; 通过串口向PC端返回当前检测的电压值。 按键“S4”定义为发送按键&#xff0c;按下按键S4&#xff0c;串口向PC端发送当前检测的电压值。 串口发送格式&#xff1a; U:1.25V\r\…