Shell 循环语句:for、while、until 实战详解

Shell 循环语句:for、while、until 实战详解

在这里插入图片描述

在 Shell 脚本中,循环语句用于重复执行一组命令,是实现“批量操作”“条件重复”的核心工具。本文围绕 forwhileuntil 三种循环,结合具体案例讲解语法与实战场景,并补充 break/continue 的用法。

一、for 循环:批量处理已知列表或范围

for 循环适合处理已知数据列表(如用户名单、IP 列表)或固定数值范围(如 1-10),通过“逐一读取数据”执行命令。

1. 基本语法

语法 1:遍历列表(最常用)
for 变量名 in 取值列表  # 取值列表:空格分隔的字符串/文件内容/命令结果
do
    命令序列  # 对每个变量值执行的命令
done
语法 2:数值范围循环(Bash 扩展)
for ((初始值; 循环条件; 自增/自减))  # 类似其他编程语言的 for 循环
do
    命令序列
done

2. 实战案例

案例 1:批量创建用户(遍历文件列表)

需求:从 users.txt 读取用户名,批量创建用户并设置统一密码。

  1. 第一步:创建用户列表文件
    [root@ansible ~]# vim /root/users.txt  # 写入以下内容,每行一个用户名
    hina
    mika
    asuka
    role
    
    
  2. 第二步:编写脚本 addusers.sh
    [root@ansible ~]# vim addusers.sh
    #!/bin/bash
    # 批量创建用户并设置密码
    read -p "请输入统一密码:" PASSWD  # 读取用户输入的密码
    
    # 遍历 users.txt 中的每个用户名
    for UNAME in `cat /root/users.txt`  # `` 表示执行命令并获取结果
    do
        useradd $UNAME  # 创建用户
        echo "$PASSWD" | passwd --stdin $UNAME  # 批量设置密码
        echo "$UNAME 创建成功!"  # 输出结果
    done
    
  3. 执行脚本(需 root 权限)
    [root@ansible ~]# chmod +x addusers.sh 
    [root@ansible ~]# ./addusers.sh 
    请输入统一密码:123456
    Changing password for user hina.
    passwd: all authentication tokens updated successfully.
    hina 创建成功!
    Changing password for user mika.
    passwd: all authentication tokens updated successfully.
    mika 创建成功!
    Changing password for user asuka.
    passwd: all authentication tokens updated successfully.
    asuka 创建成功!
    Changing password for user role.
    passwd: all authentication tokens updated successfully.
    role 创建成功!
      # 输入密码后自动创建所有用户
    
案例 2:数值范围循环(输出 1-10,步长控制)

需求 1:输出 1-10(步长 1,默认自增)

[root@ansible ~]# vim test1.sh
#!/bin/bash
for ((i=1; i<=10; i++))  # i 从 1 开始,<=10 时循环,每次+1
do
    echo $i
done

执行脚本:
[root@ansible ~]# sh test1.sh 
1
2
3
4
5
6
7
8
9
10

需求 2:输出 1-10 中的奇数(步长 2,每次+2)

[root@ansible ~]# vim test2.sh 
#!/bin/bash
for ((i=1; i<=10; i+=2))  # i 每次增加 2
do
    echo $i  # 输出:1 3 5 7 9
done

执行脚本:
[root@ansible ~]# sh test2.sh 
1
3
5
7
9

案例 3:计算 1-100 的整数和(数值循环累加)

需求:用 for 循环计算 1 到 100 的所有整数之和。

[root@ansible ~]# vim test3.sh

#!/bin/bash
sum=0  # 初始化求和变量,初始值为 0

for ((i=1; i<=100; i++))
do
    sum=$((sum + i))  # 每次循环将 i 加到 sum 中($((...)) 用于算术计算)
done

echo "1-100 的整数和为:$sum"  # 输出结果:5050

[root@ansible ~]# sh test3.sh 
1-100 的整数和为:5050
案例 4:批量检测主机存活状态(遍历 IP 列表)

需求:从 iplist.txt 读取 IP 地址,用 ping 检测主机是否在线。

  1. 第一步:创建 IP 列表文件
    vim /root/iplist.txt
    192.168.100.10
    192.168.100.20
    192.168.100.30
    
  2. 第二步:编写脚本 check_ip.sh
    #!/bin/bash
    # 批量检测 IP 存活状态
    ip_list=`cat /root/iplist.txt`  # 读取 IP 列表
    
    for ip in $ip_list
    do
        # ping 3 次(-c 3),超时 1 秒(-W 1),所有输出重定向到黑洞(&>/dev/null)
        ping -c 3 -W 1 $ip &>/dev/null
        
        if [ $? -eq 0 ]; then  # $? 为上条命令返回码,0 表示成功(主机在线)
            echo "$ip 在线"
        else
            echo "$ip 离线"
        fi
    done
    

二、while 循环:条件满足时重复执行

while 循环通过“持续检测条件”实现重复执行,只要条件为,就反复执行命令。适合处理“未知循环次数”的场景(如猜数字游戏、等待用户输入)。

1. 基本语法

while 条件测试  # 条件为真(返回码 0)时执行循环体
do
    命令序列
    (可选)自增/自减变量(避免无限循环)
done

2. 实战案例

案例 1:输出 0-10 的整数(条件控制循环次数)

需求:从 0 开始,每次+1,直到数值大于 10 时停止。

[root@ansible ~]# vim aa.sh

#!/bin/bash
a=0  # 初始化变量 a 为 0

while [ $a -le 10 ]  # 条件:a <= 10 时循环
do
    echo $a  # 输出当前 a 的值
    let a++  # 变量 a 自增 1(let 用于算术运算)
done

[root@ansible ~]# sh aa.sh 
0
1
2
3
4
5
6
7
8
9
10
案例 2:计算 1-100 的整数和(while 累加)

需求:用 while 循环替代 for,实现 1-100 求和。

[root@ansible ~]# vim bb.sh

#!/bin/bash
sum=0  # 求和变量
n=1    # 计数器变量(从 1 开始)

while [ $n -le 100 ]  # 条件:n <= 100
do
    sum=$((sum + n))  # 累加
    let n++           # 计数器+1
done

echo "1-100 的和为:$sum"  # 输出:5050

[root@ansible ~]# sh bb.sh 
1-100 的和为:5050
案例 3:随机猜数字游戏(无限循环+条件退出)

需求:生成 0-999 的随机数,让用户猜,直到猜对为止,统计猜的次数。

  • 知识点:$RANDOM 是 Bash 内置变量,生成 0-32767 的随机数;expr $RANDOM % 1000 可得到 0-999 的随机数。
[root@ansible ~]# vim bb.sh
#!/bin/bash
# 随机猜数字游戏(0-999)
num=$(expr $RANDOM % 1000)  # 生成 0-999 的随机数
count=0  # 统计猜的次数
echo "欢迎参与猜数字游戏!数字范围:0-999"

while true  # 无限循环(条件永远为真)
do
    read -p "请输入你猜的数字:" n  # 读取用户输入
    let count++  # 次数+1

    # 判断用户输入与随机数的关系
    if [ $n -eq $num ]; then
        echo "恭喜猜对了!正确数字是 $num"
        echo "你总共猜了 $count 次"
        exit 0  # 猜对后退出脚本(终止循环)
    elif [ $n -gt $num ]; then
        echo "猜大了!再试试~"
    else
        echo "猜小了!再试试~"
    fi
done

执行脚本
[root@ansible ~]# sh bb.sh 
欢迎参与猜数字游戏!数字范围:0-999
请输入你猜的数字:500
猜小了!请再试一试
请输入你猜的数字:750
猜小了!请再试一试
请输入你猜的数字:875
猜大了!请再试一试
请输入你猜的数字:812
猜大了!请再试一试
请输入你猜的数字:780
猜大了!请再试一试
请输入你猜的数字:765
猜小了!请再试一试
请输入你猜的数字:772
猜小了!请再试一试
请输入你猜的数字:776
猜大了!请再试一试
请输入你猜的数字:774
恭喜猜对了!正确数字是 774
你一共猜了 9

三、until 循环:条件不满足时重复执行

until 循环与 while 逻辑相反:只要条件为(返回码非 0),就反复执行命令;直到条件为真时停止。适合“直到某个条件达成才停止”的场景(如等待文件创建)。

1. 基本语法

until 条件测试  # 条件为假时执行循环体,条件为真时停止
do
    命令序列
done

2. 实战案例:计算 1-100 的整数和(until 实现)

需求:用 until 循环替代 while,实现 1-100 求和(条件:当 n > 100 时停止)。

[root@ansible ~]# vim cc.sh

#!/bin/bash
sum=0
n=1

# 条件:当 n > 100 时停止循环(否则继续执行)
until [ $n -gt 100 ]
do
    sum=$((sum + n))
    let n++
done

echo "1-100 的和为:$sum"  # 输出:5050

执行脚本:
[root@ansible ~]# sh cc.sh 
1-100 的和为: 5050

四、双 for 循环:循环嵌套

for 循环即“循环内部嵌套另一个循环”,外层循环控制“大范围”,内层循环控制“小范围”,适合处理“矩阵式”数据(如打印九九乘法表、多层目录创建)。

1. 基础示例:嵌套循环输出

[root@ansible ~]# vim dd.sh

#!/bin/bash
# 双 for 循环:外层控制 a(1-5),内层控制 b(1-5)
for ((a=1; a<=5; a++))
do
    echo "外层循环:a = $a"
    for ((b=1; b<=5; b++))
    do
        echo "  内层循环:b = $b"  # 缩进体现层级
    done
done

执行结果:

[root@ansible ~]# sh dd.sh 
外层循环: a =1
内层循环: b =1
内层循环: b =2
内层循环: b =3
内层循环: b =4
内层循环: b =5
外层循环: a =2
内层循环: b =1
内层循环: b =2
内层循环: b =3
内层循环: b =4
内层循环: b =5
外层循环: a =3
内层循环: b =1
内层循环: b =2
内层循环: b =3
内层循环: b =4
内层循环: b =5
外层循环: a =4
内层循环: b =1
内层循环: b =2
内层循环: b =3
内层循环: b =4
内层循环: b =5
外层循环: a =5
内层循环: b =1
内层循环: b =2
内层循环: b =3
内层循环: b =4
内层循环: b =5

2. 实战:打印九九乘法表

需求:用双 for 循环打印九九乘法表(外层控制行数,内层控制列数)。

[root@ansible ~]# vim 99.sh

#!/bin/bash
# 打印九九乘法表
for ((i=1; i<=9; i++))  # 外层循环:行数(1-9)
do
    for ((j=1; j<=i; j++))  # 内层循环:列数(1-当前行数)
    do
        echo -n "$j × $i = $((j*i))  "  # -n 不换行,保持同一行输出
    done
    echo  # 每行结束后换行
done

执行结果:

1 × 2 = 2  2 × 2 = 4  [root@ansible ~]# sh 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 

五、循环控制:break 与 continue

breakcontinue 用于在循环中控制流程,避免不必要的循环执行。

1. break:跳出当前循环

  • 作用:立即终止当前所在的循环(若嵌套循环,只跳出内层循环,外层继续)。
  • 示例:内层循环到 b=4 时跳出,外层继续执行。
[root@ansible ~]# vim dd.sh

#!/bin/bash
for ((a=1; a<=5; a++))  # 外层循环
do
    echo "外层循环:a = $a"
    for ((b=1; b<=5; b++))  # 内层循环
    do
        if [ $b -eq 4 ]; then  # 当 b=4 时
            break  # 跳出内层循环(不再执行 b=4、b=5)
        fi
        echo "  内层循环:b = $b"
    done
done

执行结果(内层只到 b=3):

[root@ansible ~]# sh dd.sh 
外层循环: a = 1
内层循环: b =1
内层循环: b =2
内层循环: b =3
外层循环: a = 2
内层循环: b =1
内层循环: b =2
内层循环: b =3
外层循环: a = 3
内层循环: b =1
内层循环: b =2
内层循环: b =3
外层循环: a = 4
内层循环: b =1
内层循环: b =2
内层循环: b =3
外层循环: a = 5
内层循环: b =1
内层循环: b =2
内层循环: b =3

2. continue:跳过当前迭代,继续下一次

  • 作用:跳过当前循环的剩余命令,直接进入下一次循环(不终止整个循环)。
  • 示例:跳过 6-9 的数字,输出 1-5 和 10-15。
[root@ansible ~]# vim ee.sh

#!/bin/bash
for ((a=1; a<=15; a++))
do
    if [ $a -gt 5 ] && [ $a -lt 10 ]; then  # 当 a 在 6-9 之间时
        continue  # 跳过当前迭代(不执行 echo),直接进入下一次循环
    fi
    echo "当前数字:$a"
done

执行结果:

[root@ansible ~]# sh ee.sh 
当前数字: 1
当前数字: 2
当前数字: 3
当前数字: 4
当前数字: 5
当前数字: 10
当前数字: 11
当前数字: 12
当前数字: 13
当前数字: 14
当前数字: 15

总结

循环类型核心场景语法特点
for已知列表(用户/IP)、固定数值范围遍历列表或 ((初始值; 条件; 自增))
while未知循环次数,条件为真时执行while 条件; do ... done
until未知循环次数,条件为假时执行until 条件; do ... done(与 while 相反)
双循环矩阵数据(乘法表、多层操作)循环嵌套,外层控范围,内层控细节

循环控制要点:

  • break:跳出当前循环(嵌套时只跳内层);
  • continue:跳过当前迭代,继续下一次;
  • 避免无限循环:确保循环内有“变量自增/条件变化”(如 let i++)。

掌握这些循环用法,可轻松实现批量创建、状态检测、数据计算等自动化任务,大幅提升运维效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值