news 2026/8/7 15:40:53

【Linux 基础知识系列:第二百零一篇】Bash 循环结构进阶:for、while 与 until

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Linux 基础知识系列:第二百零一篇】Bash 循环结构进阶:for、while 与 until

一、简介:为什么循环是 Shell 的“发动机”?

  • Shell 是 Linux 的胶水语言,循环结构负责“重复”——批量处理文件、轮询接口、守护进程、自动重试。

  • 实际场景

    • 一晚备份 500 个数据库 →for循环拼接文件名

    • 等待数据库端口存活 →while循环+sleep

    • 服务异常则一直重启 →until循环探测成功才退出

掌握for / while / until的语法差异与最佳实践,是运维、DevOps、开发者的基本功,也是写“不翻车”脚本的分水岭


二、核心概念:3 种循环一句话记住

循环关键词判断逻辑典型场景
for遍历列表列表耗尽即结束批量文件、固定次数
while条件为真入口判断,真→继续轮询、守护、读取管道
until条件为假入口判断,假→继续等待成功、自动重试

口诀:for 遍历,while 真继续,until 假继续


三、环境准备:3 分钟搞定实验沙箱

  1. 系统
    Ubuntu 20.04+/CentOS 8+/Debian 11+(Bash ≥ 4.3 即可)

  2. 权限
    普通用户可完成 90% 实验;文件系统演示需chmod +x

  3. 实验目录

    mkdir -p ~/bash-loop-lab && cd ~/bash-loop-lab
  4. 确认 Bash

    echo $BASH_VERSION # ≥ 4.3 支持关联数组、关联索引

四、实际案例与步骤:5 大关卡由浅入深

每个脚本均可直接复制,保存后chmod +x xxx.sh && ./xxx.sh跑通。


4.1 for 循环:批量重命名 + 安全前缀

需求:把 200 个.log文件加上日期前缀,防止覆盖。

#!/usr/bin/env bash # file: 01-rename.sh set -euo pipefail date_prefix=$(date +%F) for file in *.log; do [[ -f $file ]] || continue # 空目录保护 new="${date_prefix}_${file}" echo "mv $file $new" mv "$file" "$new" done echo "批量重命名完成"

技巧点

  • for file in *.log避免$(ls *.log)空格裂开的坑。

  • continue跳过目录/空匹配,脚本鲁棒性↑。


4.2 C 风格 for:固定次数倒计时

需求:脚本升级前倒计时 5 秒,可中途取消。

#!/usr/bin/env bash # file: 02-countdown.sh for ((i=5;i>0;i--)); do printf '\r升级将在 %d 秒后开始 ... 按 Ctrl+C 取消' "$i" sleep 1 done printf '\r开始升级! \n'

说明

  • 双括号(())内变量无需$前缀,支持++ -- +=

  • printf \r实现同一行动态刷新,界面友好。


4.3 while 循环:端口未就绪就等待

需求:数据库 3306 端口监听前一直重试,每 2 秒检测一次。

#!/usr/bin/env bash # file: 03-wait-port.sh HOST=127.0.0.1 PORT=3306 TIMEOUT=300 count=0 echo "等待 $HOST:$PORT 就绪 ..." while ! nc -z "$HOST" "$PORT"; do ((count++)) if [[ $count -gt $((TIMEOUT/2)) ]]; then echo "超时退出" >&2; exit 1 fi sleep 2 done echo "端口已就绪,继续执行业务 SQL ..."

依赖

  • nc(nmap-ncat):sudo dnf/apt install -y nc


4.4 until 循环:服务异常则一直重启

需求:Spring Boot jar 异常退出后 5 秒自动重启,直到手动 Ctrl+C。

#!/usr/bin/env bash # file: 04-until-restart.sh JAR=myapp.jar LOG=app.log until java -jar "$JAR" >> "$LOG" 2>&1; do echo "$(date) 服务异常退出,5 秒后重启" >&2 sleep 5 done echo "$(date) 服务正常退出,不再重启"

要点

  • until判断最后一条命令退出码,非 0 就继续循环。

  • 适合“成功即跳出”场景,逻辑比while true更清晰。


4.5 嵌套循环:批量创建目录+文件

需求:生成proj1/{src,doc,test}共 3×3=9 个目录,并在每个目录放 README.md。

#!/usr/bin/env bash # file: 05-nested.sh projects=(proj1 proj2 proj3) folders=(src doc test) for p in "${projects[@]}"; do for f in "${folders[@]}"; do dir="$p/$f" mkdir -p "$dir" echo "# $dir" > "$dir/README.md" done done echo "项目骨架生成完成"

技巧

  • 用数组+双引号避免空格分割;嵌套层级直观。


4.6 循环读取文件:行内空格安全

需求:逐行读取ip.list(格式:IP 端口),检测连通性。

#!/usr/bin/env bash # file: 06-readfile.sh INPUT=ip.list # 方式1:while read 最安全 while IFS= read -r line; do [[ -z "$line" || "$line" == \#* ]] && continue # 跳过空行与注释 ip=${line% *} port=${line#* } if nc -z "$ip" "$port"; then echo "$ip:$port OK" else echo "$ip:$port FAIL" >&2 fi done < "$INPUT"

对比

  • for i in $(cat file)会把行内空格拆成多词 →禁止

  • while read+IFS=保留原始行,100% 安全


4.7 关联数组+for:按分组批量杀进程

需求:按服务名(nginx、php、redis)分组优雅重启。

#!/usr/bin/env bash # file: 07-kill-group.sh declare -A groups=( [web]="nginx php-fpm" [cache]="redis-server" ) for group in "${!groups[@]}"; do echo "=== 重启 $group ===" for proc in ${groups[$group]}; do pkill -USR2 "$proc" # 示例信号,可换 systemctl done done

要求
Bash 4.0+ 支持关联数组;检查版本echo $BASH_VERSION


五、常见问题与解答(FAQ)

问题现象解决
Syntax error: bad for loop variableDash 执行 C 风格for ((;;))指定#!/usr/bin/env bash
ls: cannot access '*.log': No such file or directory空目录展开用 `for file in *.log; do [[ -f $file ]]continue; ...`
死循环 CPU 100%while 内无 sleepsleep 1read -t 1
read 丢失最后一行文件末尾无\n`while read -r line[[ -n $line ]]; do ... done`
变量修改在子 shell 无效管道后while用重定向< fileshopt -s lastpipe

六、实践建议与最佳实践

  1. set -euo pipefail 黄金三件套
    让脚本在变量未定义、管道失败、循环退出码非 0 时立刻失败,避免“静默继续”。

  2. 用数组+双引号代替ls

    files=(*.log) for f in "${files[@]}"; do ...
  3. 循环内打印进度

    printf '\r处理中 %d/%d' "$i" "$total"
  4. 超时退出
    自带计数器或timeout命令,防止死循环。

  5. 调试技巧

    • bash -x script.sh看每次循环变量值。

    • set +x/set -x局部开关,减少刷屏。

  6. 性能优化

    • 大量文件优先find ... -print0 | while IFS= read -r -d '' file; do ...

    • 避免在循环里cat | grep | awk三连,改用 Bash 内置参数替换。


七、总结:一张脑图带走全部要点

Bash 循环 ├─ for:列表遍历 / C 风格计数 ├─ while:条件真继续(轮询) ├─ until:条件假继续(重试) ├─ 嵌套:多级目录、多项目 ├─ read:行内空格安全 └─ 黄金习惯:引号 + -euo pipefail + 超时

掌握for / while / until语法差异、安全写法、调试技巧,你就拥有了:

  • 批量自动化的瑞士军刀:文件改名、备份、部署脚本 10 行搞定。

  • 服务守护的坚固盾牌:端口等待、异常重启、日志监控不再手写死循环。

  • 跨平台兼容的移植指南:避开$(ls)for i in $(cat file)等经典陷阱。

立刻打开终端,把本文脚本复制到~/bash-loop-lab,跑一遍、改一遍、拆一遍,写属于自己的第一个健壮循环!祝你玩得开心,循环永不死。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/7 0:01:12

打卡信奥刷题(2549)用C++实现信奥 P2113 看球泡妹子

P2113 看球泡妹子 题目背景 2014 年巴西世界杯开幕了&#xff0c;现在满城皆是世界杯&#xff0c;商家们利用它大赚一笔&#xff0c;小明和小红也借此机会增进感情。 题目描述 本届世界杯共有 nnn 支球队&#xff0c;mmm 场比赛。男球迷小明喜欢看比赛&#xff0c;女球迷小红喜…

作者头像 李华
网站建设 2026/8/7 9:55:23

四天学会一本书的公司靠谱吗

四天学会一本书的公司靠谱吗&#xff1f;深度解析速成教育的真相与选择在知识焦虑与效率至上的时代&#xff0c;“四天学会一本书”这样的宣传语无疑极具诱惑力。各类培训机构&#xff0c;尤其是以技能提升和资格认证为导向的公司&#xff0c;纷纷推出此类短期速成课程&#xf…

作者头像 李华
网站建设 2026/8/7 3:21:13

低成本高质量:为何越来越多团队选择EmotiVoice?

低成本高质量&#xff1a;为何越来越多团队选择EmotiVoice&#xff1f; 在短视频、播客和互动游戏内容爆发的今天&#xff0c;个性化语音不再只是“锦上添花”&#xff0c;而是用户体验的核心组成部分。然而&#xff0c;要实现自然流畅、富有情感、还能定制音色的语音合成&…

作者头像 李华
网站建设 2026/8/7 22:27:04

EmotiVoice与主流语音框架对比:兼容性与扩展性优势

EmotiVoice与主流语音框架对比&#xff1a;兼容性与扩展性优势 在智能内容创作和人机交互日益深化的今天&#xff0c;用户对语音合成系统的要求早已超越“能听清”的基本功能&#xff0c;转向“有情感”、“像真人”、“可定制”的高阶体验。传统云服务型TTS虽然语音自然度不断…

作者头像 李华
网站建设 2026/8/7 1:30:49

2025年网络安全人员薪酬趋势

网络安全薪资天花板&#xff1a;2025年薪酬趋势与入行指南&#xff08;建议收藏&#xff09; 文章分析了2025年网络安全行业薪酬趋势&#xff0c;指出安全架构师年薪最高&#xff08;国内150万&#xff09;&#xff0c;城市与行业显著影响收入&#xff08;一线城市比二线高30%…

作者头像 李华
网站建设 2026/8/7 22:27:34

EmotiVoice是否支持方言合成?当前进展说明

EmotiVoice 是否支持方言合成&#xff1f;技术路径与实践展望 在智能语音助手、虚拟主播和本地化内容服务日益普及的今天&#xff0c;用户对“听得懂乡音”的语音系统提出了更高期待。人们不再满足于标准普通话的机械播报&#xff0c;而是希望听到熟悉口音中流露的情感与温度—…

作者头像 李华