02 Shell 编程之条件语句

目录

2.1 条件测试语句

        2.1.1 文件测试

        2.1.2 整数值比较

        2.1.3 字符串比较

        2.1.4 逻辑测试

2.2 if 条件语句

        2.2.1 if 语句的结构

                1. 单分支if 语句

                2. 双分支if 语句

                3. 多分支if 语句

        2.2.2 if 语句应用示例

                1. 单分支if 语句应用

                2. 双分支if 语句应用

                3. 多分支if 语句应用

2.3 case 分支语句

        2.3.1 case 语句的结构

        2.3.2 case 语句应用示例

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

                2. 编写系统服务脚本


2.1 条件测试语句

        要使Shell脚本程序具备一定的"智能",面临的第一个问题就是如何区分不同的情况以确定执行何种操作。例如,当磁盘使用率超过95%时,发送告警信息;当备份目录不存在时,能够自动创建;当源码编译程序时,若配置失败则不再继续安装等。

        Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为О时表示成功,否则(非О值)表示失败或异常。使用专门的测试工具——test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值为О表示条件成立)。

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

test  条件表达式

[ 条件表达式 ]                //括号要有空格

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

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

        2.1.1 文件测试

        文件测试指的是根据给定的路径名称,判断对应的是文件还是目录,或者判断文件是否可读、可写、可执行等。文件测试的常见操作选项如下,使用时将测试对象放在操作选项之后即可。

  1. -d:测试是否为目录(directory)
  2. -e:测试目录或文件是否存在(Exist)
  3. -f:测试是否为文件(File)
  4. -r:测试当前用户是否有权限读取(Read)
  5. -w:测试当前用户是否有权限写入(Write)
  6. -x:测试是否设置有可执行(Excute)权限

        执行条件测试操作以后,通过预定义变量$?可以获得测试命令的返回状态值,从而判断该条件是否成立。例如,执行以下操作可测试目录/medial是否存在,如果返回值$?为0,表示存在此目录,否则表示不存在或者虽然存在但不是目录。

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

        例如,执行以下操作展示了测试不存在目录的情况。

        通过查看变量$?的值可以判断前一步的条件测试结果,但是操作比较烦琐,输出结果也并不是很直观。为了更直观地查看测试结果,可以结合命令分隔符“&&"和 echo命令一起使用,当条件成立时直接输出"YES”。其中,“&&""符号表示“而且"的关系,只有当前面的命令执行成功后才会执行后面的命令,否则后面的命令将会被忽略。例如,上述目录测试操作可以改写如下。

        2.1.2 整数值比较

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

  1. -eq:第一个数等于(Equal)第二个数
  2. -ne:第一个数不等于(Not Equal)第二个数
  3. -gt:第一个数大于(Greater Than)第二个数
  4. -lt:第一个数小于(Lesser Than)第二个数
  5. -le:第一个数小于或等于(Lesser or Equal)第二个数
  6. -ge:第一个数大于或等于(Greater or Equal)第二个数

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

        例如,若要判断当前已登录的用户数,当超过五个时输出"Too many.",可以执行以下操作。其中,已登录用户数可通过"who | wc-I"命令获得,以命令替换方式嵌入。

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

        2.1.3 字符串比较

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

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

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

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

        2.1.4 逻辑测试

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

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

        在上述逻辑测试的操作选项中,“&&"和“"通常也用于间隔不同的命令操作,其作用是相似的。实际上此前已经接触过“&&"操作的应用,如"make && make install"的编译安装操作。

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

2.2 if 条件语句

        实际上使用&&"和I逻辑测试已经可以完成简单的判断并执行相应的操作,但是当需要选择执行的命令语句较多时,这种方式将使执行代码显得很复杂,不好理解。而使用专用的if条件语句,可以更好地整理脚本结构,使得层次分明,清晰易懂。

        2.2.1 if 语句的结构

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

                1. 单分支if 语句

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

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

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

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

                2. 双分支if 语句

        对于双分支的选择结构,要求针对"条件成立""条件不成立"两种情况分别执行不同的操作。双分支if语句的语法格式如下所示。

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

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

                3. 多分支if 语句

        由于if语句可以根据测试结果的成立、不成立分别执行操作,所以能够嵌套使用,进行多次判断。例如,首先判断某学生的得分是否及格,若及格则再次判断是否高于90分等。多分支if语句的语法格式如下。

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

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

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

        2.2.2 if 语句应用示例

                1. 单分支if 语句应用

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

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

        当普通用户执行 chkifroot.sh脚本时,由于“非 root用户"的条件成立,因此会提示权限不足并退出脚本(使用"exit 1"退出脚本后,fi之后的fdisk命令将不会执行)。

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

                2. 双分支if 语句应用

        双分支if语句只是在单分支的基础上针对“条件不成立"的情况执行另一种操作,而不是“坐视不管"地不执行任何操作。例如,若要编写一个连通性测试脚本pinghost.sh,通过位置参数$1提供目标主机地址,然后根据 ping检测结果给出相应的提示,可以参考以下操作过程

        在上述脚本代码中,为了提高ping 命令的测试效率,使用了“-c""-""-W"选项,分别指定只发送三个测试包、间隔0.2秒、超时3秒。另外,通过"&>ldevI/null"屏蔽了ping命令执行过程的输出信息。执行pinghost.sh脚本的效果如下所示。

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

        执行chkvsftpd.sh 脚本的效果如下所示。

                3. 多分支if 语句应用

        与单分支、双分支if语句相比,多分支if语句的结构能够根据多个互斥的条件分别执行不同的操作,实际上等同于嵌套使用的if语句。例如,若要编写一个成绩分档的脚本gradediv.sh,根据输入的考试分数不同来区分优秀、合格、不合格三挡,可以参考以下操作过程。

        执行gradediv.sh 脚本的效果如下所示。

2.3 case 分支语句

        2.3.1 case 语句的结构

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

        case分支语句的语法结构如下所示。

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

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

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

        使用case分支语句时,有几个值得注意的特点如下所述。

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

        2.3.2 case 语句应用示例

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

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

        测试并确认hitkey.sh脚本的执行结果如下所示。

                2. 编写系统服务脚本

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

        在Linux系统中,源码软件包编译安装后提供的服务控制脚本使用了case分支语句;也有一些源码包没有提供服务控制脚本,编译安装后可参照上例自行编写服务控制脚本。平时控制各种系统服务时,提供的start、stop、restart等位置参数,正是由case语句结构来识别并完成相应操作的。

        若要将myprog 服务交给systemd来管理,还需要在/lib/systemd/system目录下添加相应的 myprog.service配置文件。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

chrome浏览器 network 显示感叹号(chrome network thinttling is enabled)

chrome浏览器上network出现一个黄色感叹号,鼠标移上去提示chrome network thinttling is enabled,这是因为开启了节流模式,直接把网络模式改为no throttling(有的浏览器为online)就可以了。 ##Tips: 1、n…

《图数据库:理论与实践》书籍销售火爆,二次印刷重磅来袭!

好书共享,就在此刻! 由创邻科技联合电子工业出版社匠心打磨三年,最终成稿的图数据库书籍《图数据库:理论与实践》发行上线后,获得了广泛好评,各平台销量迅速破千,并荣登京东 “数据库图书榜”热…

【Solr 学习笔记】Solr 源码启动教程

Solr 源码启动教程 本教程记录了如何通过 IDEA 启动并调试 Solr 源码,从 Solr9 开始 Solr 项目已由 ant 方式改成了 gradle 构建方式,本教程将以 Solr 9 为例进行演示,IDE 选择使用 IntelliJ IDEA。 Solr github 地址:https://gi…

牛拜克拉丝的wordpress免费企业模板

wordpress免费企业模板 挺简洁实用的wordpress免费企业模板,黄色模板搭建公司网站。 演示 https://www.wpniu.com/themes/40.html

信创CPU秘史(上):大厂销售的路子有多野?

最近接到一份金融行业粉丝的投稿,内容之奇令人咋舌,尽是些闻所未闻的新知识。无论是内容本身,还是获取内容的渠道,都非常有意思。今年我们把舞台交给老金,一起来听听信创大厂间的那些小秘密。 大家好,我叫老…

React是怎么进行事件处理的

什么是事件? 事件是指一些可以通过脚本响应的页面动作。当用户按下鼠标或者提交一个表单等等时候,事件都会出现。事件处理是一段JavaScript代码,总是与页面中的特定部分以及一定的事件相关联。当与页面特定部分相关联的事件发生时&#xff0c…

文本三剑客其二

文本三剑客其二 sed和awk grep就是查找文本当中的内容,扩展正则表达式。 sed 对文本内容进行增删改查 sed是一种流编辑器,一次处理一行内容。 如果只是展示,会放在缓冲区(模式空间),展示结束之后&…

vue3自动导入---组件库elements-ui,vuetify以及scss样式的自动导入

自动导入 我们在使用第三方组件库和css样式文件时,都需要进行引入,可以在单个组件内单独引用,也可以在全局引入或一次引入所有组件;但是,一般情况下我们都不会全部引入,这会是打包的结果变大,而…

idea插件开发之如何获取用户输入的变量名(类变量,局部变量等)

写在前面 比如我们要开发一个变量名称补全功能的插件,此时就需要在用户输入时获取当前的最新输入内容,本文就来看下如何来做。 1:开发 首先我们需要创建一个CompletionContributor的子类,还需要一个CompletionProvider的子类来…

【权威发布】2024年环境科学、旅游与产业经济国际会议(ICESTIE 2024)

2024年环境科学、旅游与产业经济国际会议 2024 International Conference on Environmental Science, Tourism and Industrial Economics 会议简介 2024年环境科学、旅游与产业经济国际会议旨在汇聚全球该领域的专家学者,共同探讨环境科学与旅游产业的融合发展&…

ArcGIS图斑分区(组)排序—从上到下从左到右

​​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 ArcGIS图斑分区(组)从上到下从左到右排序 是之前的内容的升级 GIS技巧100例——12ArcGIS图斑空间排序 关于今天的内容 我们在19年已经和大家分…

vue3 中实现 验证码发送 刷新不变倒计时

今天实现一个倒计时的功能 在平常开发前端的功能的时候 不管是 移动端还是web端 我们都会有注册 登录 中的发送验证码功能 实现绑定以及注册功能。今天我主要分享一下当前的验证码实现原理。 有两种做法(我目前认为以及看到的) ① 做一个简单的倒计时 ② 实时监测倒计时 刷…

食品行业BC一体化运营方案

一、引言 在当前的市场环境下,食品行业面临着日益激烈的竞争和不断变化的消费者需求。传统的经营模式已无法满足现代消费者对高效、便捷和个性化服务的要求。因此,实施BC(Business to Consumer)一体化运营方案成为必然选择。通过…

顶顶通呼叫中心中间件-替换授权文件使授权文件生效指南

一、登录my.ddrj.com下载授权文件 登录地址:用户-顶顶通授权管理系统 登录之后正式授权然后点击查看把license.json下载下来,然后替换到fs的授权文件路径,默认路径是:/ddt/fs/conf 如果安装路径不一样就需要自己去看看授权文件存…

分流电阻器的原理、特性、参数要点及其与分压电阻的区别详解

分流电阻器是一种低阻值电阻器,设计用于在电路中并联连接,以提供一个低阻抗的旁路或分流路径,从而使得一部分电流可以通过这个路径流动。它的主要功能是测量或限制电流,尤其适用于大电流检测的应用场景。分流电阻通过在其两端产生…

windows下cmd命令行模式中cd变换路径命令无效的解决办法

一,出现的情况 二,解决方法 当出现转换盘的时候打开 cmd 之后可能是无法生效的 ,因为在cmd 中转换盘首先需要用到换盘符 。 Solve1 : 先进行换盘 C: c: // 转换到 C盘 D: d: // 转化到 D盘 Solve2 : 直接进行强转 cd /dE:\ACM算法资源\XCP…

如何使用mvnd,随着mvnd的1.0.0发布,Maven构建速度提升了3倍不止。

maven-mvnd-1.0.0-m8-m40-windows-amd64 1、什么是 Mvnd呢 Mvnd 是 Apache Maven Daemon 的简称,是一个通过 GraalVM 构建的本地可执行文件,用于加速 Maven 构建。Mvnd 的设计理念是通过在后台运行一个守护进程来避免每次构建时启动新的 JVM&#xff0c…

【人机交互 复习】第7章 可视化设计

一、窗口界面类型 1.多文档界面 (1)优点 a.节省系统资源 b.最小的可视集 c.协同工作区 d.多文档同时可视化 (2)缺点 a.菜单随活动文档窗口状态变化,导致不一致性 b.文档窗口必须在主窗口内部,减弱多文档显…

易支付宝塔一键部署项目 懒人专用包 制作

宝塔一键部署说明 https://www.bt.cn/bbs/thread-33063-1-1.html 1. auto_install.json {"php_ext":"fileinfo","chmod":[],"success_url":"install/?step3&jump1","php_versions":"80","db…

mybatis查询PostgreSQL报错:无法确定参数 $1 的数据类型

错误信息 ### Cause: org.postgresql.util.PSQLException: 错误: 无法确定参数 $1 的数据类型 ; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: 错误: 无法确定参数 $1 的数据类型] with root cause org.postgresql.util.PSQLException: 错误: …