循环是 Bash 脚本中一个非常强大且常用的功能,它能帮助我们自动化执行重复性任务。无论是遍历文件、处理数组还是等待某个条件满足,循环都是核心工具。
在这一节,我们将系统地探索 Bash 中三种主流的循环结构:for、while 和 until。你将学会如何使用它们遍历数组元素,并掌握 break 和 continue 语句来控制循环流程。最后,我们还会讨论无限循环的成因与用途。
for循环
for 循环主要有两种风格,一种是类似C语言的风格,另一种则更擅长处理列表。
C语言风格的for循环
如果你有C、C++或Java等语言的编程经验,那么下面的语法会非常熟悉:
for ((initialize ; condition ; increment)); do
[COMMANDS]
done
下面的脚本 forhello.sh 就使用这种风格的 for 循环来输出10次 “Hello Friend”:
for ((i = 0 ; i < 10 ; i++)); do
echo "Hello Friend"
done
循环的执行过程是:首先将整数变量 i 初始化为0;只要条件 i < 10 为真,就执行 echo “Hello Friend”;每次循环结束后,将 i 的值加1;当 i 不再小于10时,循环结束。

遍历列表或数组的for循环
这种形式的 for 循环在处理文件列表、字符串、数字序列、数组或命令输出时特别方便,其语法如下:
for item in [LIST]; do
[COMMANDS]
done
例如,下面的 for 循环与上面的C风格循环功能完全相同,它使用了大括号展开 {1..10} 来生成一个1到10的数字序列:
for i in {1..10}; do
echo "Hello Friend"
done
另一个更实用的例子是遍历目录。下面的 var.sh 脚本会输出 /var/ 目录下所有子目录的路径:
#!/bin/bash
for i in /var/*; do
echo $i
done

While循环
while 循环是另一种直观且流行的循环结构。它的逻辑是:只要条件为真,就继续执行。其通用语法如下:
while [ condition ]; do
[COMMANDS]
done
下面的 3x10.sh 脚本使用 while 循环来打印数字3的前10个倍数:
#!/bin/bash
num=1
while [ $num -le 10 ]; do
echo $((num * 3))
num=$((num+1))
done
它首先将变量 num 初始化为1。只要 num 的值小于或等于10,循环就会不断执行:先计算并打印 num * 3 的结果,然后将 num 的值加1。

Until循环
如果你有C语言的背景,可能会寻找 do-while 循环。Bash中没有 do-while,但它提供了 until 循环。语法与 while 相似:
until [ condition ]; do
[COMMANDS]
done
until 循环与 while 循环的关键区别在于判断条件。while 在条件为真时运行,而 until 在条件为假时运行。
我们可以用 until 循环重构上面的 3x10.sh 例子:
#!/bin/bash
num=1
until [ $num -gt 10 ]; do
echo $((num * 3))
num=$((num+1))
done
你会发现,判断条件从 [ $num -le 10 ](小于等于10为真)变成了 [ $num -gt 10 ](大于10为真)。循环会一直执行,直到 num 大于10的条件变为真时才停止。
更多循环的用法
掌握了三种基本循环结构后,我们来看一些进阶用例。
打印数组中的元素
要遍历数组,for 循环是最常用的方法。下面的 prime.sh 脚本演示了如何遍历并打印一个包含素数的数组:
#!/bin/bash
prime=(2 3 5 7 11 13 17 19 23 29)
for i in "${prime[@]}"; do
echo $i
done

使用 Break 和 Continue
有时我们需要更精细地控制循环流程,这时 break 和 continue 语句就派上用场了。
break:立即终止整个循环,将控制权交给循环后的下一条命令。
continue:跳过当前循环中剩余的语句,直接开始下一次循环迭代。
下面的例子中,循环本应打印1到10,但当 i 等于3时,break 语句被执行,循环提前终止:
for ((i=1;i<=10;i++)); do
echo $i
if [ $i -eq 3 ]; then
break
fi
done

continue 语句常用于跳过某些特定情况。下面的 odd.sh 脚本只打印1到10之间的奇数,遇到偶数时则使用 continue 跳过:
#!/bin/bash
for ((i=1;i<=10;i++)); do
if [ $(($i % 2)) -ne 1 ]; then
continue
fi
echo $i
done

无限循环
无限循环是指会永远执行下去的循环,这通常发生在循环条件始终为真时。
在大多数情况下,无限循环是编程时的逻辑错误。例如,有人想创建一个降序打印10到1的循环,却不小心写成了递增:
for ((i=10;i>0;i++)); do
echo $i
done
这个循环中,i 从10开始,条件是 i > 0,但每次迭代后执行的是 i++(增加),所以 i 永远大于0,导致无限循环。正确的写法应该是 i--。
当然,在某些特定场景下,我们可能需要主动创建无限循环,例如编写一个一直等待用户输入或监控系统状态的守护进程脚本。
创建一个无限循环很简单,以下是两种常见写法:
for 循环风格(省略所有三个表达式):
for ((;;)); do
[COMMANDS]
done
while 循环风格:
while [ true ]; do
[COMMANDS]
done
练习题
自己动手练习是巩固知识的最佳方式。这里有几道基于上述内容的练习题,建议你亲自尝试一下。
练习 1:循环消息
创建一个 for 循环,在命令行显示10次同一条消息,并运行这个脚本。
难度:容易
提示:在 for 循环内使用 echo 打印消息。
练习 2:用for循环列出目录内容
编写脚本,输出 /var 目录下存在的所有文件和目录。
难度:中等
提示:使用 /var/* 作为 for 循环的遍历列表。
练习 3:使用while循环进行3的倍数运算
使用 while 循环,输出数字3的前十个倍数。
难度:容易
提示:初始化变量为1;当变量小于等于10时循环;循环体内打印变量乘以3,然后变量加1。
练习 4:使用until循环进行3的倍数运算
使用一个 until 循环来实现练习3的相同功能。
难度:简单
提示:until 循环在条件为假时运行。思考如何将 while 的条件取反。
练习 5:带循环的数组迭代
创建一个存储前十个素数的数组。遍历数组并打印其中的每一个元素。
难度:中等
提示:使用 for item in “${array[@]}” 的语法来遍历数组。
练习题答案
以下是练习题的参考脚本,建议先自己编写,再进行比较。
答案 1:循环消息
#!/bin/bash
for ((i = 0 ; i < 10 ; i++)); do
echo “Hello World!”
done
答案 2:用for循环列出目录内容
#!/bin/bash
for i in /var/*; do
echo $i
done
答案 3:使用while循环进行3的倍数运算
#!/bin/bash
num=1
while [ $num -le 10 ]; do
echo $((num * 3))
num=$((num+1))
done
答案 4:使用until循环进行3的倍数运算
#!/bin/bash
num=1
until [ $num -gt 10 ]; do
echo $((num * 3))
num=$((num+1))
done
答案 5:带循环的数组迭代
#!/bin/bash
prime=(2 3 5 7 11 13 17 19 23 29)
for i in “${prime[@]}”; do
echo $i
done
希望这篇关于 Bash 循环的详细解析和实战练习能帮助你巩固基础。脚本编写是运维工作中的重要技能,熟练掌握循环将使你的自动化任务如虎添翼。如果你想讨论更多脚本案例或分享学习心得,欢迎来 云栈社区 交流探讨。