当前位置: 首页 > ops >正文

【运维进阶】case、for、while、until语句大合集

case、for、while、until语句大合集

case 条件语句的应用实践

case 条件语句的语法

case 条件语句的语法格式为:

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

变量:通常是脚本传入的参数,如 $1

模式:支持字符串、通配符(*?)、多个模式(a|b|c)。

;;:表示该分支结束。

*:相当于 default,匹配不到时执行。

esac:表示 case 语句结束(反过来的 case)。

为了便于大家记忆,下面是某女生写的case 条件语句的中文形象描述:

case "找老公条件" in资产大于1千万)嫁给你;;资产介于1百万和1千万之间)再考虑以下;;资产小于1百万)再见;;其他情况)视情况而定;;
esac

case 条件语句实践

**示例:**模拟 Linux 服务管理脚本的实现

# 服务管理脚本1
# 用 case...esac 语句来控制 sshd 服务的 启动、停止和状态查看。
[root@controller bin 20:12:44]# vim case1_sshd
[root@controller bin 20:12:51]# cat case1_sshd 
#!/bin/bash
case $1 instart)systemctl start sshd;;stop)systemctl stop sshd;;status)systemctl status sshd;;*)echo "Usage: $0 start | stop | status";;
esac# 根据传入的第一个参数($1)来决定执行哪一个分支。
# 如果参数不是 start|stop|status,就打印提示用法。# 执行脚本时不加参数
# 走到了 *) 分支,提示加参数。
[root@controller bin 20:13:08]# bash case1_sshd 
Usage: case1_sshd start | stop | status
[root@controller bin 20:13:16]# bash case1_sshd stop
[root@controller bin 20:13:20]# bash case1_sshd status
● sshd.service - OpenSSH server daemonLoaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor
preset: enabled)Active: inactive (dead) since 日 2025-08-24 20:13:20 CST; 4s agoDocs: man:sshd(8)man:sshd_config(5)
...
[root@controller bin 20:13:35]# bash case1_sshd start
[root@controller bin 20:13:53]# bash case1_sshd status
● sshd.service - OpenSSH server daemonLoaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)Active: active (running) since 日 2025-08-24 20:13:53 CST; 
...
# 服务管理脚本2
# 模式合并(start|stop|status)来减少重复代码。
[root@controller bin 20:16:38]# vim case2_sshd
[root@controller bin 20:16:47]# cat case2_sshd 
#!/bin/bash
case $1 instart|stop|status)systemctl $1 sshd # 用 $1 直接把参数传给systemctl,一行就能搞定三个情况。;;*)echo "Usage: $0 start | stop | status";;
esac[root@controller bin 20:16:55]# bash case2_sshd
Usage: case2_sshd start | stop | status
[root@controller bin 20:17:21]# bash case2_sshd stop
[root@controller bin 20:17:29]# bash case2_sshd status
● sshd.service - OpenSSH server daemonLoaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)Active: inactive (dead) since 日 2025-08-24 20:17:29 CST; 3s agoDocs: man:sshd(8)man:sshd_config(5)
...
[root@controller bin 20:17:39]# bash case2_sshd start
[root@controller bin 20:17:51]# bash case2_sshd status
● sshd.service - OpenSSH server daemonLoaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)Active: active (running) since 日 2025-08-24 20:17:51 CST; 1s agoDocs: man:sshd(8)man:sshd_config(5)
...

case 语句核心总结

  • 核心特点
    • 适用于多分支判断场景
    • 比 if…elif…else 结构更简洁直观
    • 语法格式固定:case 变量 in … 分支 … esac
  • 典型应用场景
    • 菜单选择:交互式脚本中处理用户输入的选项
    • 参数处理:解析命令行参数(如 -h、-v 等选项)
    • 服务管理:处理服务的 start/stop/restart/status 等指令
  • 优势
    • 逻辑层次清晰,便于维护
    • 减少冗余判断代码
    • 对固定值匹配场景适配性强

for 循环语句的应用实践

for循环语句和while循环语句类似,但for循环语句主要用于执行次数有限的循环,而不是用于守护进程及无限循环。

for 循环语法结构

Shell 脚本中 for 循环的两种语法结构及说明:

一、变量取值型(列表遍历式)
语法结构
for 变量名 in 变量取值列表
do指令...
done
关键说明
  1. 结构特点

    • 通过 in 关键字指定变量的取值列表(元素以空格分隔)
    • 可省略 in 变量取值列表,此时默认等价于 in "$@"(即遍历脚本的位置参数)
  2. 执行流程

    • 变量依次获取列表中的每个值
    • 每次取值后执行 dodone 之间的循环指令
    • 直到取完列表中所有值,循环结束
  3. 示例

    # 遍历指定列表
    for fruit in apple banana orange
    doecho "当前水果:$fruit"
    done# 省略列表(等价于 in "$@")
    for arg
    doecho "参数:$arg"
    done
    
二、C 语言型(表达式控制式)
语法结构
for ((exp1; exp2; exp3))
do指令...
done
关键说明
  1. 表达式含义

    • exp1:变量初始化(如 i=0
    • exp2:循环条件判断(如 i<10
    • exp3:变量迭代操作(如 i++i--
  2. 执行流程

    • 先执行 exp1 初始化变量
    • 判断 exp2 是否成立:成立则执行循环体,不成立则退出循环
    • 每次循环结束后执行 exp3 更新变量,再重复判断 exp2
  3. 示例

    # 计数从1到5
    for ((i=1; i<=5; i++))
    doecho "计数:$i"
    done
    

两种结构对比:

  • 变量取值型:适合遍历已知列表(如文件列表、参数列表)
  • C 语言型:适合需要精确控制循环次数的场景(如固定范围计数)

for循环结构执行流程对应的逻辑图如下:

在这里插入图片描述

for 循环语句的基础实践

示例1:三对情侣参加婚礼

3个新郎为A、B、C,3个新娘为X、Y、Z。有人想知道究竟谁与谁结婚,于是就问新人中的三位,得到如下结果:

  • A说他将和X结婚;
  • X说她的未婚夫是C;
  • C说他将和Z结婚。

这人事后知道他们说的全是假话。那么,究竟谁与谁结婚呢?

[root@controller bin 20:36:20]# vim marry.sh 
[root@controller bin 20:36:29]# cat marry.sh 
#!/bin/bash
# 外层循环:为A选择配偶,从X、Y、Z中取值
for A in X Y Z
do# 中层循环:为B选择配偶,从X、Y、Z中取值for B in X Y Zdo# 内层循环:为C选择配偶,从X、Y、Z中取值for C in X Y Zdo# 条件判断:筛选符合所有规则的组合# 1. A、B、C的配偶必须互不相同(三个不等条件)# 2. A的配偶不能是X# 3. C的配偶不能是X# 4. C的配偶不能是Zif [ "$A" != "$B" -a "$A" != "$C" -a "$B" != "$C" -a "$A" != "X" -a "$C" != "X" -a "$C" != "Z" ];then# 输出符合条件的组合echo A 与 $A 结婚echo B 与 $B 结婚echo C 与 $C 结婚fidonedone
done# 执行
[root@controller bin 20:36:47]# bash marry.sh A 与 Z 结婚B 与 X 结婚C 与 Y 结婚
示例2:九九乘法表
[root@controller bin 16:10:08]# vim 99.sh
[root@controller bin 16:10:59]# cat 99.sh 
#!/bin/bash
# 外层for循环(变量取值型):控制乘法表的“行数”(即第二个乘数)
# {1..9}是Shell的序列表达式,等价于1 2 3 ... 9,num1依次取1到9的值
for num1 in {1..9}
do# 内层for循环(C语言型):控制每行的“列数”(即第一个乘数)# 初始值num2=1,循环条件num2<=num1(保证每行列数不超过行数,避免重复),每次循环num2自增1for ((num2=1;num2<=num1;num2++))do# 输出乘法表达式:-e启用转义字符,-n不自动换行(让同一行内容连在一起)# $num2*$num1:显示“第一个乘数*第二个乘数”的格式# $[ num2 * num1 ]:Shell算术扩展,计算num2和num1的乘积(等价于$((num2*num1)))# \t:插入制表符,让每行内容对齐(避免因数字位数不同导致错乱)echo -en "$num2*$num1=$[ num2 * num1 ]\t"done# 内层循环结束后,执行一次空echo:手动换行,让下一行从新的一行开始echo
done# 执行
[root@controller bin 16:11:05]# bash 99.sh 
1*1=1   
1*2=2   2*2=4   
1*3=3   2*3=6   3*3=9   
1*4=4   2*4=8   3*4=12  4*4=16  
1*5=5   2*5=10  3*5=15  4*5=20  5*5=25  
1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36  
1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49  
1*8=8   2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64  
1*9=9   2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81  

while 循环和 until 循环的应用实践

当型和直到型循环语法

while 循环语句

while 循环是 Shell 脚本中用于 “条件成立时重复执行操作” 的循环结构,核心逻辑是 “先判断条件,条件满足才执行循环”,具体说明如下:

while 循环语句的基本语法为:
while <条件表达式>
do指令...
done

提示:注意代码缩进(比如循环体指令缩进 2-4 个空格),能让代码逻辑更清晰,方便后续阅读和维护。

核心执行逻辑
  1. 先判断,再执行:循环启动后,会先检查 while 后面的<条件表达式>是否成立(比如 “变量 i 小于 10”“文件存在” 等)。
  2. 条件成立则执行循环体:如果条件表达式结果为 “真”,就会执行 dodone 之间的所有 “指令”(这部分叫循环体)。
  3. 循环判断,直到条件不成立:每次执行完循环体里的所有指令、走到 done 时,会再次回到 while 处重新判断条件;只要条件还成立,就重复执行循环体,直到某一次判断时条件不成立,才会跳出循环,继续执行 done 后面的代码。
  4. 初始条件不成立则不进循环:如果第一次判断条件时,表达式结果就是 “假”,那么循环体(dodone 之间的内容)会直接跳过,一句指令都不执行。
形象化理解(中文场景举例)

用日常生活场景类比,能更直观记住 while 循环的逻辑,比如 “是否继续和男朋友相处” 的判断:

# 逻辑:只要“男朋友努力工作”这个条件成立,就执行“继续相处”的操作
while 男朋友努力工作
do继续相处
done

这里的逻辑和代码完全对应:先看 “男朋友努力工作” 是否为真,是就 “继续相处”;每次 “相处” 后,会再检查一次这个条件,只要条件还满足就一直相处,直到条件不满足(比如男朋友不努力了),就停止 “继续相处”。

while 循环执行流程对应的逻辑图如下:

在这里插入图片描述

until 循环语句

until 循环是 Shell 脚本中与 while 循环逻辑相反的循环结构,核心特点是 “条件不成立时重复执行,条件成立时停止”,可以理解为 “直到条件满足才退出循环”,具体说明如下:

一、基本语法
until <条件表达式>
do指令...
done
二、核心执行逻辑
  1. 先判断条件,不成立才执行:循环启动后,首先检查 until 后面的 <条件表达式> 是否成立。
  2. 条件不成立则进入循环体:如果条件表达式结果为 “假”(不成立),就会执行 dodone 之间的 “指令”(即循环体);如果条件一开始就成立,循环体则会直接跳过,一句指令都不执行。
  3. 循环判断,直到条件成立:每次执行完循环体的所有指令、走到 done 时,会再次返回 until 处重新判断条件;只要条件仍然不成立,就重复执行循环体,直到某一次判断时条件 “成立”(结果为真),才会立即跳出循环,继续执行 done 之后的代码。

简单来说,until 循环的逻辑是:“只要条件没满足,就一直做;等条件满足了,就不做了”,这是它和 while 循环(“条件满足才做,不满足就不做”)最核心的区别。

三、形象化理解(中文场景举例)

用日常生活中的 “是否继续相处” 场景类比,能更直观记住 until 循环的逻辑,比如通过 “男朋友是否不努力工作” 来决定是否停止相处:

# 逻辑:直到“男朋友不努力工作”这个条件成立,才停止“继续相处”;只要这个条件不成立(男朋友努力),就一直相处
until 男朋友不努力工作
do继续相处 
done

这里的逻辑和代码完全对应:先看 “男朋友不努力工作” 是否成立 —— 如果不成立(说明男朋友在努力),就 “继续相处”;每次 “相处” 后,会再检查一次条件,只要 “男朋友不努力” 这个条件没出现,就一直相处;直到某一次发现 “男朋友不努力工作”(条件成立),就停止 “继续相处”,跳出循环。

until 循环执行流程对应的逻辑图如下:

在这里插入图片描述

当型和直到型循环的基本范例

示例:

[root@controller bin 21:31:18]# vim target.sh
[root@controller bin 21:31:26]# cat target.sh 
#!/bin/bash
# 定义目标金额变量target,设定为10000000(即1000万,作为循环停止的条件阈值)
target=10000000
# 定义当前金额变量money,初始值设为0(表示一开始没有钱)
money=0# until循环:判断条件为“当前金额>=目标金额”
# 核心逻辑:只要条件不成立(money < 1000万),就反复执行循环体;直到条件成立(money >= 1000万),停止循环
until (($money>=$target))
do# 循环体指令1:输出工作赚钱的提示信息,模拟“正在努力赚钱”的过程echo "I'm working hard to get money..."# 循环体指令2:sleep 1 表示暂停1秒再执行后续代码,模拟赚钱需要消耗时间的过程sleep 1# 循环体指令3:更新当前金额,每次在原有money基础上增加1000000(即100万)# $[ 表达式 ] 是Shell算术扩展语法,用于计算“money + 1000000”的结果并赋值给moneymoney=$[ money + 1000000 ]# 循环体指令4:输出当前最新的金额,让用户看到赚钱进度echo "I have $money."
done# 循环结束后执行的指令:当money >= 1000万时,跳出循环,输出“jiejiejie”(模拟达成目标后的欢呼)
echo jiejiejie# 执行
[root@controller bin 21:31:39]# bash target.sh 
I'm working hard to get money...
I have 1000000.
I'm working hard to get money...
I have 2000000.
I'm working hard to get money...
I have 3000000.
I'm working hard to get money...
I have 4000000.
I'm working hard to get money...
I have 5000000.
I'm working hard to get money...
I have 6000000.
I'm working hard to get money...
I have 7000000.
I'm working hard to get money...
I have 8000000.
I'm working hard to get money...
I have 9000000.
I'm working hard to get money...
I have 10000000.
jiejiejie
http://www.xdnf.cn/news/18616.html

相关文章:

  • VSCode+Qt+CMake详细地讲解
  • 嵌入式系统bringup通用流程
  • halcon(一)一维码解码
  • 目标检测数据集 第007期-基于yolo标注格式的茶叶病害检测数据集(含免费分享)
  • MATLAB 入门:从变量定义到基础绘图的完整上手指南
  • 05-ArkUI界面开发
  • 前端漏洞(上)- CSRF漏洞
  • C++ Core Guidelines: 最佳实践与深入解析
  • .net9 解析 jwt 详解
  • Go语言 Hello World 实例
  • RabbitMQ--消费端异常处理与 Spring Retry
  • 2025最新ncm转MP3,网易云ncm转mp3格式,ncm转mp3工具!
  • ThinkPHP8学习篇(四):请求和响应
  • VSCode无权访问扩展市场
  • 【数据结构】-5- 顺序表 (下)
  • 【JavaEE】了解synchronized
  • Java 基础学习总结(211)—— Apache Commons ValidationUtils:让参数校验从 “体力活“ 变 “优雅事“
  • 电动车运行原理与最新人工智能驾驶技术在电动车上的应用展望:从基础动力系统到L5级完全自动驾驶的技术深度解析
  • 大语言模型的自动驾驶 LMDrive/DriveVLM-Dual
  • Kubernetes部署Prometheus+Grafana 监控系统NFS存储方案
  • Spark04-MLib library01-机器学习的介绍
  • Spring创建的方式
  • 在 Ubuntu 24.04 或 22.04 LTS 服务器上安装、配置和使用 Fail2ban
  • 【LLM】DeepSeek-V3.1-Think模型相关细节
  • Android - 用Scrcpy 将手机投屏到Windows电脑上
  • MySQL学习记录-基础知识及SQL语句
  • SSRF的学习笔记
  • React useState 全面深入解析
  • 6.2 el-menu
  • Axure RP 9的安装