2026/4/17 22:36:19
网站建设
项目流程
湖北网站建设,wordpress 慢2017,平江网站设计多少钱,网站上怎么做返回主页链接一、简介#xff1a;为什么循环是 Shell 的“发动机”#xff1f;Shell 是 Linux 的胶水语言#xff0c;循环结构负责“重复”——批量处理文件、轮询接口、守护进程、自动重试。实际场景一晚备份 500 个数据库 → for 循环拼接文件名等待数据库端口存活 → while 循环sleep…一、简介为什么循环是 Shell 的“发动机”Shell 是 Linux 的胶水语言循环结构负责“重复”——批量处理文件、轮询接口、守护进程、自动重试。实际场景一晚备份 500 个数据库 →for循环拼接文件名等待数据库端口存活 →while循环sleep服务异常则一直重启 →until循环探测成功才退出掌握for / while / until的语法差异与最佳实践是运维、DevOps、开发者的基本功也是写“不翻车”脚本的分水岭。二、核心概念3 种循环一句话记住循环关键词判断逻辑典型场景for遍历列表列表耗尽即结束批量文件、固定次数while条件为真入口判断真→继续轮询、守护、读取管道until条件为假入口判断假→继续等待成功、自动重试口诀for 遍历while 真继续until 假继续。三、环境准备3 分钟搞定实验沙箱系统Ubuntu 20.04/CentOS 8/Debian 11Bash ≥ 4.3 即可权限普通用户可完成 90% 实验文件系统演示需chmod x实验目录mkdir -p ~/bash-loop-lab cd ~/bash-loop-lab确认 Bashecho $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 ((i5;i0;i--)); do printf \r升级将在 %d 秒后开始 ... 按 CtrlC 取消 $i sleep 1 done printf \r开始升级 \n说明双括号(())内变量无需$前缀支持 -- 。printf \r实现同一行动态刷新界面友好。4.3 while 循环端口未就绪就等待需求数据库 3306 端口监听前一直重试每 2 秒检测一次。#!/usr/bin/env bash # file: 03-wait-port.sh HOST127.0.0.1 PORT3306 TIMEOUT300 count0 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 ...依赖ncnmap-ncatsudo dnf/apt install -y nc4.4 until 循环服务异常则一直重启需求Spring Boot jar 异常退出后 5 秒自动重启直到手动 CtrlC。#!/usr/bin/env bash # file: 04-until-restart.sh JARmyapp.jar LOGapp.log until java -jar $JAR $LOG 21; do echo $(date) 服务异常退出5 秒后重启 2 sleep 5 done echo $(date) 服务正常退出不再重启要点until判断最后一条命令退出码非 0 就继续循环。适合“成功即跳出”场景逻辑比while true更清晰。4.5 嵌套循环批量创建目录文件需求生成proj1/{src,doc,test}共 3×39 个目录并在每个目录放 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 INPUTip.list # 方式1while 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 readIFS保留原始行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 bashls: cannot access *.log: No such file or directory空目录展开用 for file in *.log; do [[ -f $file ]]continue; ...死循环 CPU 100%while 内无 sleep加sleep 1或read -t 1read 丢失最后一行文件末尾无\nwhile read -r line[[ -n $line ]]; do ... done变量修改在子 shell 无效管道后while用重定向 file或shopt -s lastpipe六、实践建议与最佳实践set -euo pipefail 黄金三件套让脚本在变量未定义、管道失败、循环退出码非 0 时立刻失败避免“静默继续”。用数组双引号代替lsfiles(*.log) for f in ${files[]}; do ...循环内打印进度printf \r处理中 %d/%d $i $total超时退出自带计数器或timeout命令防止死循环。调试技巧bash -x script.sh看每次循环变量值。set x/set -x局部开关减少刷屏。性能优化大量文件优先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跑一遍、改一遍、拆一遍写属于自己的第一个健壮循环祝你玩得开心循环永不死。