Shell脚本-for循环应用案例
一、前言
在 Linux Shell 脚本编程中,for
循环 是最常用的控制结构之一,它可以帮助我们自动化重复性任务,如批量处理文件、遍历目录、执行命令等。
本文将通过 10 个真实应用场景,带你深入掌握 Shell 脚本中 for
循环的使用技巧,涵盖文件操作、系统管理、日志处理等多个方面,助你提升自动化运维能力。
二、Shell 中 for 循环的基本语法
1. 标准 for 循环语法
for 变量 in 列表
do命令
done
或简写为一行:
for 变量 in 列表; do 命令; done
2. C 风格 for 循环(适用于计数)
for (( i=1; i<=10; i++ ))
doecho $i
done
三、10 个实用应用案例
✅ 案例 1:批量创建文件
#!/bin/bash
for i in {1..5}
dotouch file_$i.txtecho "已创建 file_$i.txt"
done
用途:快速生成测试文件。
✅ 案例 2:批量重命名文件
将 file_1.txt
改为 backup_1.txt
#!/bin/bash
for file in file_*.txt
domv "$file" "${file/file_/backup_}"echo "已重命名: $file -> ${file/file_/backup_}"
done
技巧:
${var/pattern/replacement}
实现字符串替换。
✅ 案例 3:批量修改文件权限
为所有 .sh
脚本添加可执行权限:
#!/bin/bash
for script in *.sh
doif [ -f "$script" ]; thenchmod +x "$script"echo "已添加执行权限: $script"fi
done
建议:加上
-f
判断是否为文件,避免误操作。
✅ 案例 4:遍历目录中的所有文件
#!/bin/bash
for file in /home/user/documents/*
doif [ -f "$file" ]; thenecho "文件: $(basename "$file")"elif [ -d "$file" ]; thenecho "目录: $(basename "$file")"fi
done
说明:
basename
用于提取文件名。
✅ 案例 5:批量压缩文件
将每个 .txt
文件单独压缩为 .gz
格式:
#!/bin/bash
for file in *.txt
doif [ -f "$file" ]; thengzip "$file"echo "已压缩: $file.gz"fi
done
✅ 案例 6:检查多个主机是否在线(Ping 扫描)
#!/bin/bash
for ip in 192.168.1.{1..10}
doping -c 1 -W 1 $ip &> /dev/nullif [ $? -eq 0 ]; thenecho "$ip 在线"elseecho "$ip 离线"fi
done
技巧:
&> /dev/null
静默输出,$?
获取上一条命令返回值。
✅ 案例 7:批量添加用户
#!/bin/bash
for username in user1 user2 user3
doid $username &> /dev/nullif [ $? -ne 0 ]; thenuseradd -m $usernameecho "用户 $username 创建成功"elseecho "用户 $username 已存在"fi
done
注意:生产环境建议设置密码或使用
chpasswd
。
✅ 案例 8:清理过期日志文件(按天)
删除 7 天前的日志:
#!/bin/bash
for log in /var/log/app/*.log.*
doif [ -f "$log" ]; then# 获取文件修改时间距今天数days_old=$(( ( $(date +%s) - $(stat -c %Y "$log") ) / 86400 ))if [ $days_old -gt 7 ]; thenrm -f "$log"echo "已删除: $log"fifi
done
✅ 案例 9:循环执行命令并记录日志
每 5 秒监控一次系统负载:
#!/bin/bash
for (( i=1; i<=10; i++ ))
doload=$(uptime | awk '{print $(NF-2)}' | sed 's/,//')echo "$(date): 系统负载 $load" >> /tmp/monitor.logsleep 5
done
用途:简单性能监控脚本。
✅ 案例 10:读取文件内容逐行处理
#!/bin/bash
filename="hosts.txt"
for host in $(cat $filename)
doecho "正在处理: $host"# 示例:尝试连接# ping -c 1 $host &> /dev/null && echo "$host 可达"
done
⚠️ 注意:如果文件包含空格,建议使用
while read
更安全。
更安全的写法:
while read host; doecho "处理: $host"
done < hosts.txt
四、常见问题与注意事项
问题 | 原因 | 解决方法 |
---|---|---|
文件名含空格导致错误 | for 默认按空格分割 | 使用 while read 或加引号 |
变量未定义 | 变量名拼写错误 | 使用 set -u 检查未定义变量 |
路径未加引号 | 路径含空格时报错 | 所有变量加双引号:"$var" |
死循环 | 条件判断错误 | 仔细检查循环条件 |
权限不足 | 脚本无执行权限 | chmod +x script.sh |
五、for 循环优化技巧
- 使用
{1..10}
替代seq 1 10
:更高效,无需调用外部命令。 - 避免在循环中频繁调用外部命令:尽量将命令合并。
- 使用
&&
和||
简化逻辑:[ -f "$file" ] && echo "存在" || echo "不存在"
- 结合管道与循环:
ls *.log | while read file; do ... done
六、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!