找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1322

积分

0

好友

170

主题
发表于 10 小时前 | 查看: 3| 回复: 0

循环是 Bash 脚本中一个非常强大且常用的功能,它能帮助我们自动化执行重复性任务。无论是遍历文件、处理数组还是等待某个条件满足,循环都是核心工具。

在这一节,我们将系统地探索 Bash 中三种主流的循环结构:forwhileuntil。你将学会如何使用它们遍历数组元素,并掌握 breakcontinue 语句来控制循环流程。最后,我们还会讨论无限循环的成因与用途。

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 循环在处理文件列表、字符串、数字序列、数组或命令输出时特别方便,其语法如下:

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

遍历/var目录的脚本与输出

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。

while循环计算3的倍数

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

有时我们需要更精细地控制循环流程,这时 breakcontinue 语句就派上用场了。

  • break:立即终止整个循环,将控制权交给循环后的下一条命令。
  • continue:跳过当前循环中剩余的语句,直接开始下一次循环迭代。

下面的例子中,循环本应打印1到10,但当 i 等于3时,break 语句被执行,循环提前终止:

for ((i=1;i<=10;i++)); do
  echo $i
  if [ $i -eq 3 ]; then
    break
  fi
done

使用break语句提前终止循环

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

使用continue跳过偶数,只输出奇数

无限循环

无限循环是指会永远执行下去的循环,这通常发生在循环条件始终为真时。

在大多数情况下,无限循环是编程时的逻辑错误。例如,有人想创建一个降序打印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 循环的详细解析和实战练习能帮助你巩固基础。脚本编写是运维工作中的重要技能,熟练掌握循环将使你的自动化任务如虎添翼。如果你想讨论更多脚本案例或分享学习心得,欢迎来 云栈社区 交流探讨。




上一篇:Ubuntu 24.04系统安装TFTP服务器指南:轻量级网络文件传输配置
下一篇:Redux设计哲学解析:状态管理的可预测性与Zustand的轻量便捷如何选择
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-10 19:34 , Processed in 0.391138 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表