第 37 课:for 与 while 循环
学习目标
通过本课的学习,你将能够:
- 掌握
for循环的基本语法与多种常用格式。 - 掌握
while循环的基本语法与使用场景。 - 理解
for循环与while循环的核心区别,并能根据需求选择合适的循环。 - 学会使用
break和continue来控制循环流程。 - 能够运用循环完成简单的系统管理批处理任务。
核心概念
循环,就是让计算机重复做某件事。在 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:综合练习 - 批量创建文件
要求:编写一个脚本,结合循环和条件判断完成以下任务:
- 使用
for循环生成 1 到 5 的数字。 - 在循环体内,判断数字是否大于 2。
- 如果大于 2,则创建一个名为
report_数字.txt的空文件(例如report_3.txt)。 - 最后,使用
ls -l report_*.txt命令列出所有生成的报告文件。
常见错误
-
for循环中变量忘记加$:# 错误!`i` 被当作字符串而不是变量 for i in 1 2 3; do echo i; done # 正确 for i in 1 2 3; do echo $i; done -
while循环条件没有更新导致死循环:# 错误!count 永远是 1,条件永远成立 count=1 while [ $count -le 5 ]; do echo $count # 忘记 ((count++)),程序会卡在这里 done -
for循环in后的列表问题:- 如果列表项包含空格,需要用引号括起来或用其他方式处理。
for i in *.txt非常方便,但如果当前目录没有.txt文件,循环体仍会执行一次,变量i的值就是*.txt这个字面字符串。可以用shopt -s nullglob来避免这个问题(让未匹配的通配符扩展为空)。
-
混淆
for和while的使用场景:- 试图用
while去遍历一个固定列表,虽然能实现,但不如for直观。 - 试图用
for去实现需要持续判断条件的循环(如监控日志),会非常困难。
- 试图用
小结
本课我们学习了 Shell 脚本中最重要的两种循环结构:
for循环:核心是 “遍历”。当你明确知道要处理的数据列表(文件、数字序列、字符串)时,它是最佳选择。语法清晰,不易出错。while循环:核心是 “判断”。当你需要根据某个条件是否持续为真来决定是否继续循环时使用,例如读取文件、等待进程结束等。- 控制语句:
break用于提前退出整个循环,continue用于跳过本次循环进入下一轮。
掌握循环是编写自动化脚本、处理批量任务的基础。通过组合 for/while 与其他 Shell 命令(如 ls, cat, grep),你可以极大地提升系统管理工作的效率。下一课,我们将学习如何使用函数来组织和复用这些循环代码块。