37·Shell 基础进阶

for 与 while 循环

forwhileloops

第 37 课:for 与 while 循环

学习目标

通过本课的学习,你将能够:

  1. 掌握 for 循环的基本语法与多种常用格式。
  2. 掌握 while 循环的基本语法与使用场景。
  3. 理解 for 循环与 while 循环的核心区别,并能根据需求选择合适的循环。
  4. 学会使用 breakcontinue 来控制循环流程。
  5. 能够运用循环完成简单的系统管理批处理任务。

核心概念

循环,就是让计算机重复做某件事。在 Shell 脚本中,我们最常用的两种循环是 for 循环和 while 循环。

1. for 循环:遍历一个“清单” 你可以把 for 循环想象成“拿着清单去采购”。清单上列好了所有需要买的东西(比如:苹果、香蕉、牛奶),你按照清单一项一项地去拿,拿完列表里的最后一项,循环就结束了。它特别适合用于处理已知数量的一组事物,比如文件列表、一系列数字或字符串。

2. while 循环:满足条件就一直做 while 循环更像一个“守卫”。它会不断检查一个条件是否成立(比如:信号灯是不是红灯?)。只要条件成立(是红灯),它就一直执行某个动作(等待)。一旦条件不成立了(变绿灯),它就停止。它非常适合用于需要持续检查直到某个状态发生改变的场景,比如读取文件直到读完,或者不断监控某个进程。

3. 控制循环:break 与 continue

  • break:立即“跳出”并终止整个循环。就像采购时接到紧急电话,直接放弃购物回家。
  • continue:跳过本次循环剩下的命令,直接进入“下一次”循环。就像在采购清单上看到“芹菜”不喜欢,直接跳过,开始找“牛奶”。

代码示例

示例 1:基础 for 循环

#!/bin/bash
# 示例1:遍历一个单词列表
echo "--- 遍历列表 ---"
for fruit in apple banana cherry
do
    echo "I like $fruit."
done
echo ""

# 示例2:遍历数字序列(使用 {start..end} 格式)
echo "--- 倒数计时 ---"
for i in {5..1}
do
    echo "Countdown: $i"
    sleep 1 # 暂停1秒
done
echo "Go!"

# 示例3:遍历命令的输出结果
echo ""
echo "--- /etc 目录下的 .conf 文件 ---"
for config_file in $(ls /etc/*.conf 2>/dev/null)
do
    echo "Found: $config_file"
done

示例 2:基础 while 循环

#!/bin/bash
# 示例1:基于计数器的 while 循环
echo "--- 使用while计数 ---"
count=1
while [ $count -le 5 ] # 当 count <= 5 时执行
do
    echo "Loop number: $count"
    ((count++)) # count = count + 1
done

# 示例2:逐行读取文件(一种经典用法)
echo ""
echo "--- 读取 /etc/hosts 文件前3行 ---"
line_number=0
while IFS= read -r line # `read`命令从标准输入读取一行到变量`line`
do
    ((line_number++))
    echo "Line $line_number: $line"
    if [ $line_number -ge 3 ]; then
        break # 读完前3行就跳出循环
    fi
done < /etc/hosts # 将文件内容作为 while 循环的输入

示例 3:break 与 continue

#!/bin/bash
# 使用 break 在遇到特定值时停止
echo "--- 寻找数字5 ---"
for num in 1 2 3 4 5 6 7
do
    if [ $num -eq 5 ]; then
        echo "Found number 5! Breaking out of the loop."
        break
    fi
    echo "Processing number: $num"
done

echo ""

# 使用 continue 跳过偶数
echo "--- 只打印奇数 ---"
for i in {1..10}
do
    # 如果i除以2余数为0(是偶数),则跳过本次循环的剩余命令
    if [ $((i % 2)) -eq 0 ]; then
        continue
    fi
    echo "Odd number: $i"
done

实践练习

练习 1:基础 for 循环

要求:编写一个脚本,使用 for 循环打印出数字 1 到 10,每个数字占一行。 预期输出

1
2
3
...
10

练习 2:使用 while 循环读取文件

要求:创建一个文本文件 users.txt,内容为几个用户名(每行一个)。编写一个脚本,使用 while 循环逐行读取这个文件,并为每个用户名打印 “Hello, [用户名]!”。 文件 users.txt 内容示例

alice
bob
charlie

预期输出

Hello, alice!
Hello, bob!
Hello, charlie!

练习 3:综合练习 - 批量创建文件

要求:编写一个脚本,结合循环和条件判断完成以下任务:

  1. 使用 for 循环生成 1 到 5 的数字。
  2. 在循环体内,判断数字是否大于 2。
  3. 如果大于 2,则创建一个名为 report_数字.txt 的空文件(例如 report_3.txt)。
  4. 最后,使用 ls -l report_*.txt 命令列出所有生成的报告文件。

常见错误

  1. for 循环中变量忘记加 $

    # 错误!`i` 被当作字符串而不是变量
    for i in 1 2 3; do echo i; done
    # 正确
    for i in 1 2 3; do echo $i; done
    
  2. while 循环条件没有更新导致死循环

    # 错误!count 永远是 1,条件永远成立
    count=1
    while [ $count -le 5 ]; do
        echo $count
        # 忘记 ((count++)),程序会卡在这里
    done
    
  3. for 循环 in 后的列表问题

    • 如果列表项包含空格,需要用引号括起来或用其他方式处理。
    • for i in *.txt 非常方便,但如果当前目录没有 .txt 文件,循环体仍会执行一次,变量 i 的值就是 *.txt 这个字面字符串。可以用 shopt -s nullglob 来避免这个问题(让未匹配的通配符扩展为空)。
  4. 混淆 forwhile 的使用场景

    • 试图用 while 去遍历一个固定列表,虽然能实现,但不如 for 直观。
    • 试图用 for 去实现需要持续判断条件的循环(如监控日志),会非常困难。

小结

本课我们学习了 Shell 脚本中最重要的两种循环结构:

  • for 循环:核心是 “遍历”。当你明确知道要处理的数据列表(文件、数字序列、字符串)时,它是最佳选择。语法清晰,不易出错。
  • while 循环:核心是 “判断”。当你需要根据某个条件是否持续为真来决定是否继续循环时使用,例如读取文件、等待进程结束等。
  • 控制语句break 用于提前退出整个循环,continue 用于跳过本次循环进入下一轮。

掌握循环是编写自动化脚本、处理批量任务的基础。通过组合 for/while 与其他 Shell 命令(如 ls, cat, grep),你可以极大地提升系统管理工作的效率。下一课,我们将学习如何使用函数来组织和复用这些循环代码块。

练习编辑器

rust
Loading...

继续学习

完成本课后,建议继续学习下一课「Shell 函数定义与使用」 以巩固所学知识。