Linux Shell 编程之条件语句详解

Linux Shell编程之条件语句

Shell脚本是Linux系统自动化运维、批量处理任务的核心工具,而条件语句是让Shell脚本拥有“判断能力”的关键,能根据不同条件执行不同操作,让脚本从简单的命令拼接升级为具备逻辑思维的程序。本文将从基础的条件测试操作入手,详细讲解if条件语句和case分支语句的使用,并补充实用知识点,内容简易易懂、侧重实操。

一、基础条件测试操作

Shell通过返回状态值判断命令执行结果,返回0表示成功/条件成立,非0表示失败/条件不成立。条件测试是实现判断的基础,专门用于检测文件状态、数值大小、字符串匹配等情况,核心有两种写法,方括号写法更常用:

  1. test 条件表达式
  2. [ 条件表达式 ]

注意:方括号与条件表达式之间必须有至少一个空格,这是Shell语法的硬性要求,遗漏会直接报错。

根据测试对象不同,条件测试分为文件测试整数值比较字符串比较逻辑测试四类,以下是最常用的测试选项及实操示例。

1. 文件测试:判断文件/目录的状态

针对文件或目录的路径,检测其是否存在、类型、权限等,操作选项放在测试对象前,常用选项如下:

选项

作用

-d

测试是否为目录(Directory)

-e

测试文件/目录是否存在(Exist)

-f

测试是否为普通文件(File)

-r

测试当前用户是否有读取权限(Read)

-w

测试当前用户是否有写入权限(Write)

-x

测试当前用户是否有执行权限(Execute)

示例:测试/tmp/test是否为目录 [ -d /tmp/test ] echo $? (查看前一条命令的返回值,返回0为成立 非0为不成立)
示例:测试/tmp/test是否为目录,存在则输出“存在” [ -d /tmp/test ] && echo "存在" (无输出表示该目录不存在,输出则表示存在)

&&为逻辑与,仅当前面命令执行成功(条件成立)时,才执行后面的命令。

2. 整数值比较:判断两个整数的大小

仅适用于整数比较,不能用于小数/字符串,操作选项放在两个整数之间,常用选项如下:

选项

作用

-eq

两数相等(Equal)

-ne

两数不相等(Not Equal)

-gt

第一个数大于第二个数(Greater Than)

-lt

第一个数小于第二个数(Lesser Than)

-le

第一个数小于等于第二个数

-ge

第一个数大于等于第二个数

示例:判断当前登录用户数是否超过3,超过则提示“用户过多” num=$(who | wc -l) # 提取登录用户数 [ $num -gt 3 ] && echo "用户过多"

3. 字符串比较:判断字符串是否匹配/为空

用于检测字符串是否相同、是否为空,常用于判断用户输入、系统环境变量,常用选项如下:

选项

作用

=

两个字符串完全相同(注意是单等号)

!=

两个字符串不相同,其中“!”符号表示取反

-z

测试字符串是否为空(长度为0)

-n

测试字符串是否非空(长度不为0)

示例1:判断系统语言是否为中文,非中文则提示 [ $LANG != "zh_CN.UTF-8" ] && echo "当前非中文环境" 示例2:判断用户输入是否为空,为空则提示 read -p "请输入内容:" input [ -z $input ] && echo "输入内容不能为空"

4. 逻辑测试:判断多个条件的关系

用于组合多个测试条件,判断其“与/或/非”关系,常用操作如下(推荐符号写法,更直观):

操作符

作用

等价写法(test命令用)

&&

逻辑与:多个条件同时成立才成立

-a

||

逻辑或:多个条件一个成立就成立

-o

!

逻辑非:取反,条件不成立时结果才成立

!

示例:判断整数num是否在10~20之间 num=15 [ $num -ge 10 ] && [ $num -le 20 ] && echo "在10~20之间" 补充:逻辑非的使用,测试/tmp/test是否不是目录 [ ! -d /tmp/test ] && echo "不是目录或不存在"

补充知识点1:条件测试的简化输出

除了&&,还可搭配||(逻辑或)实现“条件成立输出A,不成立输出B”,无需额外语句,极简实用: # 测试/tmp/test是否存在,存在输出“存在”,否则输出“不存在” [ -e /tmp/test ] && echo "存在" || echo "不存在"

二、if条件语句:按条件执行不同命令序列

条件测试仅能实现简单的判断输出,当需要根据条件执行多条命令时,需使用if条件语句。根据逻辑复杂度,分为单分支双分支多分支三种结构,核心特点是层次清晰、适合多条件嵌套

1. 单分支if语句:条件成立才执行

适用场景:仅需要在“条件成立”时执行命令,条件不成立则无操作。

语法格式

if 条件测试操作

then

    命令序列 # 条件成立时执行,可写多条命令

fi # 结束if判断,不可省略

​​​​​​​示例:检测备份目录/data/backup是否存在,不存在则创建 #!/bin/bash BACKUP_DIR="/data/backup" if [ ! -d $BACKUP_DIR ] then mkdir -p $BACKUP_DIR echo "备份目录创建成功:$BACKUP_DIR" fi

2. 双分支if语句:条件成立/不成立分别执行

适用场景:需要对“条件成立”和“条件不成立”两种情况分别执行不同命令序列,是最常用的结构。

语法格式

if 条件测试操作

then

   命令序列1 # 条件成立执行

else

    命令序列2 # 条件不成立执行

fi

示例:检测目标主机是否连通,连通则提示在线,否则提示离线 #!/bin/bash IP=$1 # 接收位置参数,指定目标IP ping -c 2 -i 0.5 -W 2 $IP &>/dev/null # 发送2个包,超时2秒,屏蔽输出 if [ $? -eq 0 ] # $?获取上一条命令返回值,0表示ping通 then echo "主机$IP 在线" else echo "主机$IP 离线" fi 执行效果: bash ping_host.sh 192.168.1.100 # 检测192.168.1.100

3. 多分支if语句:多个条件依次判断

适用场景:存在多个互斥条件,需要依次判断,满足某个条件则执行对应命令,所有条件都不满足则执行默认命令。

语法格式

if 条件测试操作1

then

  命令序列1 # 条件1成立执行

elif 条件测试操作2

then

     命令序列2 # 条件2成立执行 # 可添加多个elif条件

else

    命令序列n # 所有条件都不成立执行

fi

示例:根据用户输入的分数,判断成绩等级(85+优秀、60~84及格、60以下不及格,可以检测输入的是不是数字如不是会提升输入数字而不是符号或其他,数字不会超过100) vim aaa.sh #!/bin/bash # 循环接收输入,直到输入合法 while true; do read -p "输入您的分数(0-100):" GRADE # 第一步:正则校验是否为纯数字(仅允许0-9的数字,无其他字符) if ! [[ $GRADE =~ ^[0-9]+$ ]]; then echo "错误:请输入纯数字,请勿输入字母、符号或空格!" continue fi # 第二步:校验数字是否在0-100范围内 if [ $GRADE -lt 0 ] || [ $GRADE -gt 100 ]; then echo "错误:分数范围必须在0-100之间,请重新输入!" continue fi # 输入合法,退出循环 break done # 原有分数等级判断逻辑 if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]; then echo "$GRADE 分,优秀!" elif [ $GRADE -ge 60 ] && [ $GRADE -le 84 ]; then echo "$GRADE 分,合格!" else echo "$GRADE 分,不及格!" fi 执行: bash aaa.sh (然后输入自己的数字)

补充知识点2:if语句的条件拓展

if后的条件测试操作不仅可以是[ 表达式 ],还可以是任意Linux命令,Shell会根据命令的返回值判断:返回0则条件成立,非0则不成立。

示例:直接用ping命令作为if条件,简化主机连通性检测

if ping -c 2 192.168.1.100 &>/dev/null then echo "主机在线" else echo "主机离线" fi

三、case分支语句:匹配变量的多个取值

case语句与多分支if语句功能类似,专门适用于“一个变量有多个固定取值,每个取值对应不同操作” 的场景,相比多分支if语句,case语句语法更简洁、可读性更高,无需多次写条件测试,仅需匹配变量取值。

1. case语句的基本语法

核心特点:按顺序匹配变量的取值,匹配成功则执行对应命令序列,匹配后直接退出(无需判断后续条件),无匹配项则执行默认操作。

case 变量值 in

模式1)

    命令序列1

    ;; # 结束当前模式,不可省略,相当于“break”

模式2)

    命令序列2

    ;; # 可添加多个模式

*) # 通配符,匹配所有未定义的模式,即默认模式 默认命令序列

esac # 结束case判断,不可省略

2. 模式匹配规则(实用拓展)

case的模式支持通配符和范围匹配,让取值匹配更灵活,常用规则:

  1. [a-z]:匹配小写字母a到z的任意一个;
  2. [0-9]:匹配数字0到9的任意一个;
  3. A|B:匹配A或B,如start|begin
  4. *:通配符,匹配任意字符(即默认模式*);
  5. ?:匹配单个任意字符。

3. case语句实操示例

示例1:判断用户输入的字符类型
提示用户输入一个字符,判断其是字母、数字还是其他字符: #!/bin/bash read -p "请输入一个字符:" key case $key in [a-z]|[A-Z]) # 匹配任意字母 echo "您输入的是【字母】" ;; [0-9]) # 匹配任意数字 echo "您输入的是【数字】" ;; *) # 匹配其他所有字符 echo "您输入的是【特殊字符/空格/功能键】" esac
示例2:编写简易服务控制脚本
模拟Linux系统服务的start/stop/restart/status控制,实现对sleep进程的启停管理(sleep仅作测试,可替换为实际服务如nginx): #!/bin/bash # 服务控制脚本:./service.sh start/stop/restart/status case $1 in start) echo -n "正在启动服务..." sleep 3600 &>/dev/null & # 后台启动sleep进程 echo "启动成功" ;; stop) echo -n "正在停止服务..." pkill sleep &>/dev/null # 终止sleep进程 echo "停止成功" ;; restart) $0 stop # $0表示当前脚本名,调用自身的stop操作 $0 start # 调用自身的start操作 echo "重启成功" ;; status) if pgrep sleep &>/dev/null; then echo "服务【运行中】" else echo "服务【已停止】" fi ;; *) echo "用法:$0 {start|stop|restart|status}" # 提示正确用法 esac 执行效果: bash service.sh start # 启动服务 bash service.sh status # 查看状态 bash service.sh stop # 停止服务

补充知识点3:if与case的适用场景对比

if和case都能实现多条件判断,核心区别在于判断依据,实际使用中按以下原则选择,让脚本更简洁:

  1. 用if的场景:判断多个不同的条件(如数值范围、多个文件状态、混合条件),或条件之间有嵌套关系;
  2. 用case的场景:判断一个变量的多个固定取值(如服务的start/stop、字符类型、菜单选择),取值为离散的固定值。

四、核心语法注意事项(避坑重点)

  1. 方括号[ ]与条件表达式之间必须有空格,如[ $num -gt 10 ],不可写为[$num -gt 10]
  2. 变量取值建议用双引号包裹,避免因空格、特殊字符导致报错,如[ -z "$input" ]
  3. case语句中,每个模式必须以)结束,命令序列后必须加;;,否则脚本执行异常;
  4. 整数值比较不能用>/<,Shell中</>是重定向符号,会导致语法错误,必须用-gt/-lt等;
  5. 字符串比较的=前后建议加空格,避免与变量赋值混淆(赋值是变量=值,无空格)。

五、本章小结

  1. 条件测试是Shell判断的基础,分为文件、整数值、字符串、逻辑四类,[ 表达式 ]是最常用写法;
  2. if条件语句分单/双/多分支,适合多条件、多场景的逻辑判断,支持命令作为条件;
  3. case分支语句适合单变量的多固定取值匹配,语法简洁、执行效率高,支持通配符模式匹配;
  4. 实际脚本编写中,根据判断依据选择if或case,同时注意Shell的语法细节,避免空格、符号等低级错误。

掌握条件语句后,Shell脚本将具备基本的逻辑处理能力,后续可结合循环语句实现更复杂的自动化任务(如批量检测主机、批量备份文件、自动化部署服务等),是Linux自动化运维的必备基础。

Read more

Java 时间类(中):JDK8 全新时间 API 详细教程

Java 时间类(中):JDK8 全新时间 API 详细教程

🏠个人主页:黎雁 🎬作者简介:C/C++/JAVA后端开发学习者 ❄️个人专栏:C语言、数据结构(C语言)、EasyX、JAVA、游戏、规划、程序人生 ✨ 从来绝巘须孤往,万里同尘即玉京 文章目录 * Java 时间类(中):JDK8 全新时间 API 详细教程 🕘 * 📝 文章摘要 * 🧠 上篇知识回顾 * 一、JDK8 时间类整体架构 🏛 * 二、ZoneId 时区类 🌍 * 1. 核心作用 * 2. 常用方法 * 3. 代码示例 * 三、Instant 时间戳类 ⚡ * 1. 核心作用 * 2. 常用方法 * 3. 代码示例 * 四、ZonedDateTime

By Ne0inhk
JAVA IO流:从基础原理到实战应用

JAVA IO流:从基础原理到实战应用

JAVA IO流:从基础原理到实战应用 1.1 本章学习目标与重点 💡 掌握IO流的核心概念与分类,理解字节流与字符流的区别和适用场景。 💡 熟练使用字节流完成文件的读取与写入操作,解决文件拷贝等实际问题。 💡 掌握字符流的使用方法,处理文本文件的编码与解码问题。 💡 了解缓冲流、转换流、对象流等高级IO流的原理,提升IO操作效率。 ⚠️ 本章重点是 字节流与字符流的核心用法 和 高级IO流的实战应用,这是JAVA文件操作的必备技能。 1.2 IO流核心概念与分类 1.2.1 什么是IO流 💡 IO流(Input/Output Stream)是JAVA中用于处理设备之间数据传输的技术,主要负责数据的读取(Input)和写入(Output)。 常见的IO操作包括文件读写、网络通信数据传输等。IO流的核心思想是以流的方式处理数据,数据像水流一样从一个设备流向另一个设备,实现数据的传输与处理。 1.2.2 IO流的分类标准 JAVA中的IO流体系庞大,可按照不同标准进行分类,核心分类方式有以下三种: 1.

By Ne0inhk
依托Java和百度地图实现长沙市热门道路与景点实时路况检索的实践探索

依托Java和百度地图实现长沙市热门道路与景点实时路况检索的实践探索

目录 前言 一、实时路况服务简介 1、实时路况服务是什么 2、道路实时路况查询 3、周边实时路况查询 4、返回参数 二、Java响应对象封装 1、响应对象设计 2、响应对象实现 三、UniHttp集成及调用 1、检索接口声明 2、道路实时路况查询 3、周边实时路况查询 四、常见问题 1、道路名称错误 2、中心点坐标位置错误 3、坐标类型错误 4、命名的小插曲 五、总结 前言         在当今数字化时代,交通出行的便捷性与高效性已成为衡量城市智慧化水平的重要指标之一。随着城市化进程的加速,长沙市作为湖南省的省会城市,其交通流量日益复杂,再叠加现在的国庆旅游客流和中秋探亲客流,热门道路与景点的路况信息对于市民日常出行和游客旅游规划至关重要。因此,需要开发一套能够实时检索长沙市热门道路与景点路况的系统。         本实践探索旨在通过Java编程语言调用百度地图的API接口,实现对长沙市热门道路与景点的实时路况检索功能。

By Ne0inhk
java( Java 25 LTS)的下载、安装、配置 (IDEA 2025 为例)

java( Java 25 LTS)的下载、安装、配置 (IDEA 2025 为例)

一、Java 25 LTS 下载 Java 下载 |神谕https://www.oracle.com/java/technologies/downloads/#jdk25-windows 二、安装 2.1Windows 图形安装 首先双击下载的 jdk25.msi 文件,进入安装向导。 选择 Next 进入下一步。修改安装路径(建议 D:\Java\jdk-25)确保路径简洁无中文或空格。 勾选 Generate public JRE 选项,保持默认配置。 点击 Install 开始安装,完成后点击 Finish。 2.2macOS 安装 双击下载的 jdk-25.

By Ne0inhk