Shell脚本:条件判断(case语句)与循环(for、while)

一、条件判断:case语句

1. 基本概念

case语句用于基于变量的值进行多分支匹配,类似其他语言中的switch-case。它会依次检查变量是否匹配某个模式,匹配成功则执行对应分支,直到遇到;;结束当前分支。


2. 基本语法格式

case 变量引用 in
  PAT1)      # 模式1(支持通配符)
    分支1代码  # 匹配PAT1时执行的命令
    ;;       # 结束当前分支(类似break)
  PAT2)      # 模式2
    分支2代码
    ;;
  ...
  *)         # 默认分支(类似其他语言的default)
    默认代码  # 所有模式都不匹配时执行
    ;;
esac         # 结束case语句(固定写法)

3. 支持的通配符(glob风格)

通配符

作用

示例

*

任意长度的任意字符

*.sh(所有.sh文件)

?

任意单个字符

file?.txt(如file1.txt)

[]

指定范围内的任意单个字符

[abc](a或b或c)

`

`

或关系


4. 使用示例

示例1:基础交互判断
#!/bin/bash
read -p "Do you agree(yes/no)?" INPUT  # 提示用户输入yes/no

# 统一转为小写(避免大小写敏感)
INPUT=$(echo $INPUT | tr 'A-Z' 'a-z')

case $INPUT in
  y|yes)  
    echo "You input is Yes"  # 匹配y或yes
    ;;
  n|no)
    echo "You input is No"   # 匹配n或no
    ;;
  *)
    echo "Input false, please input yes or no!"  # 其他情况(默认分支)
    ;;
esac

运行效果:​

  • 输入yes→ 输出You input is Yes

  • 输入NO→ 输出You input is No(自动转小写后匹配n|no

  • 输入abc→ 输出Input false...


示例2:菜单选择(工作选项)
#!/bin/bash
# 显示菜单选项
cat <<EOF
请选择:
1.备份文件
2.清理日志文件
3.软件升级
4.软件回滚
5.删库跑路
EOF

read -p "请输入上面的数字1-5:" MENU  # 用户输入数字

case $MENU in
  1)
    ./backup.sh  # 执行备份脚本
    ;;
  2)
    echo "清理日志"
    ;;
  3)
    echo "软件升级"
    ;;
  4)
    echo "软件回滚"
    ;;
  5)
    echo "删库跑路"
    ;;
  *)
    echo "Input False"  # 非1-5的输入
    ;;
esac

二、循环结构

1. 循环的基本逻辑

循环的作用是重复执行某段代码,直到满足特定条件才停止。循环通常包含两个关键部分:

  • 进入条件​:判断是否开始循环(如循环次数未达到上限)。

  • 退出条件​:判断何时停止循环(如循环次数用完或任务完成)。


2. for循环

(1)基本语法(格式1)
# 写法1(推荐)
for 变量 in 列表; do
  循环体  # 每次循环执行的代码
done

# 写法2(换行更清晰)
for 变量 in 列表
do
  循环体
done

执行机制​:

依次将列表中的每个元素赋值给变量,每赋值一次就执行一次循环体,直到列表中的元素全部用完。


(2)列表的生成方式

方式

示例

说明

直接列出元素

for i in 1 2 3 4; do ...

直接写要遍历的值(空格分隔)

整数范围({start..end})​

for i in {1..5}; do ...

生成1,2,3,4,5

带步长的整数范围

for i in {1..10..2}; do ...

生成1,3,5,7,9(步长为2)

seq命令生成序列

for i in $(seq 1 5); do ...

生成1,2,3,4,5(等价于{1..5})

命令返回的结果

for file in $(ls *.txt); do ...

遍历当前目录下所有.txt文件

通配符(glob)​

for file in *.sh; do ...

遍历当前目录下所有.sh文件

位置参数($@)​

for arg in $@; do ...

遍历脚本的所有输入参数


示例1:基础数字遍历
for i in 1 2 3 4 5; do
  echo "i=$i"
done
# 输出:i=1 → i=2 → ... → i=5
示例2:使用{start..end}生成整数序列
for i in {1..5}; do
  echo "数字:$i"
done
# 输出:数字:1 → 数字:2 → ... → 数字:5

# 带步长(每2个数)
for i in {1..10..2}; do
  echo "奇数:$i"
done
# 输出:奇数:1 → 奇数:3 → ... → 奇数:9
示例3:计算1到100的和
sum=0
for i in {1..100}; do
  let sum+=i  # 等价于 sum=$((sum + i))
done
echo "1到100的和为:$sum"  # 输出5050
示例4:遍历命令结果(如文件列表)
# 遍历/var/log/下所有.log文件
for file in /var/log/*.log; do
  echo "日志文件:$file"
  ls -l $file  # 查看文件详情
done
示例5:打印99乘法表
for i in {1..9}; do          # 外层循环控制行数(1到9)
  for j in $(seq $i); do     # 内层循环控制每行的列数(1到当前行数i)
    echo -e "${j}x$i=$((j*i))\t\c"  # 输出乘法结果(\t制表符,\c不换行)
  done
  echo  # 每行结束后换行
done

效果:​

1x1=1	
1x2=2	2x2=4	
1x3=3	2x3=6	3x3=9	
...(后续行省略)

(3)双小括号语法(格式2,类似C语言风格)
for ((控制变量初始化; 条件判断; 控制变量修正)); do
  循环体
done

特点​:

  • 1、更接近C语言的for循环写法(如for(int i=1; i<=10; i++))。
  • 2、适合需要精确控制变量增减的场景。

示例1:1到100求和
sum=0
for ((i=1; i<=100; i++)); do  # 初始化i=1,条件i<=100,每次循环后i++
  let sum+=i
done
echo "和为:$sum"  # 输出5050
示例2:打印直角三角形(星号)
for ((i=1; i<=5; i++)); do      # 行数1到5
  for ((j=1; j<=i; j++)); do    # 每行星号数等于行号i
    echo -e "*\c"
  done
  echo  # 换行
done
# 输出:
# *
# **
# ***
# ****
# *****

3. while循环

(1)基本语法
while 条件判断; do
  循环体  # 当条件为True时执行的代码
done

执行机制​:

先检查条件判断是否为True(非零值),若为True则执行循环体,执行完后再次检查条件,直到条件为False(零值)时退出循环。


(2)常见用法
① 无限循环(需配合break或外部终止)
while true; do
  循环体  # 一直执行,除非手动终止脚本或内部用break退出
done
② 条件控制的循环(如猜数字游戏)
#!/bin/bash
# 生成1~100的随机数
num=$((RANDOM % 100 + 1))  # RANDOM是系统变量(0~32767),取余后+1得到1~100

echo "已生成1~100的随机数,开始猜吧!"

while true; do  # 无限循环,直到猜对
  read -p "请输入你猜的数字(1~100):" guess
  
  if [ $guess -eq $num ]; then
    echo "🎉 恭喜!猜对了,数字就是 $num"
    break  # 退出循环
  elif [ $guess -gt $num ]; then
    echo "太大了!再试试更小的数字"
  else
    echo "太小了!再试试更大的数字"
  fi
done
③ 持续监控服务器负载
#!/bin/bash
# 功能:每300秒检查一次服务器负载,超过1.0时发送警告邮件
while true; do
  load=$(uptime | awk '{print $10}' | tr -d ',')  # 获取负载值(去掉逗号)
  if [ $(echo "$load > 1.0" | bc) -eq 1 ]; then   # 用bc计算浮点数比较
    echo "⚠️ 警告:服务器负载过高(当前负载:$load)" | mail -s "负载警告" admin@example.com
  fi
  sleep 300  # 等待300秒(5分钟)
done
④ 逐行读取文件内容
#!/bin/bash
# 功能:逐行读取文件并打印
filename="data.txt"
while read line; do
  echo "当前行内容:$line"
done < "$filename"  # 将文件内容通过输入重定向给while

三、总结对比

结构

适用场景

特点

case

多分支条件判断(如菜单选择)

根据变量的值匹配模式,执行对应分支,适合替代多层if-elif-else

for

已知循环次数或遍历列表

通过列表(数字、文件、命令结果等)驱动循环,支持整数范围、通配符等

while

未知循环次数(条件控制)

根据条件(如文件存在、网络连通等)决定是否继续循环,适合监控类任务


提示​:编写循环时,务必确保有明确的退出条件,否则可能导致死循环(脚本卡死)!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值