Shell脚本-for循环应用案例

一、前言

在 Linux Shell 脚本编程中,for 循环 是最常用的控制结构之一,它可以帮助我们自动化重复性任务,如批量处理文件、遍历目录、执行命令等。

本文将通过 10 个真实应用场景 ,带你深入掌握 Shell 脚本中 for 循环的使用技巧,涵盖文件操作、系统管理、日志处理等多个方面,助你提升自动化运维能力。

二、Shell 中 for 循环的基本语法

1. 标准 for 循环语法

bash 复制代码
for 变量 in 列表
do
    命令
done

或简写为一行:

bash 复制代码
for 变量 in 列表; do 命令; done

2. C 风格 for 循环(适用于计数)

bash 复制代码
for (( i=1; i<=10; i++ ))
do
    echo $i
done

三、10 个实用应用案例

✅ 案例 1:批量创建文件

bash 复制代码
#!/bin/bash
for i in {1..5}
do
    touch file_$i.txt
    echo "已创建 file_$i.txt"
done

用途:快速生成测试文件。

✅ 案例 2:批量重命名文件

file_1.txt 改为 backup_1.txt

bash 复制代码
#!/bin/bash
for file in file_*.txt
do
    mv "$file" "${file/file_/backup_}"
    echo "已重命名: $file -> ${file/file_/backup_}"
done

技巧${var/pattern/replacement} 实现字符串替换。

✅ 案例 3:批量修改文件权限

为所有 .sh 脚本添加可执行权限:

bash 复制代码
#!/bin/bash
for script in *.sh
do
    if [ -f "$script" ]; then
        chmod +x "$script"
        echo "已添加执行权限: $script"
    fi
done

建议 :加上 -f 判断是否为文件,避免误操作。

✅ 案例 4:遍历目录中的所有文件

bash 复制代码
#!/bin/bash
for file in /home/user/documents/*
do
    if [ -f "$file" ]; then
        echo "文件: $(basename "$file")"
    elif [ -d "$file" ]; then
        echo "目录: $(basename "$file")"
    fi
done

说明basename 用于提取文件名。

✅ 案例 5:批量压缩文件

将每个 .txt 文件单独压缩为 .gz 格式:

bash 复制代码
#!/bin/bash
for file in *.txt
do
    if [ -f "$file" ]; then
        gzip "$file"
        echo "已压缩: $file.gz"
    fi
done

✅ 案例 6:检查多个主机是否在线(Ping 扫描)

bash 复制代码
#!/bin/bash
for ip in 192.168.1.{1..10}
do
    ping -c 1 -W 1 $ip &> /dev/null
    if [ $? -eq 0 ]; then
        echo "$ip 在线"
    else
        echo "$ip 离线"
    fi
done

技巧&> /dev/null 静默输出,$? 获取上一条命令返回值。

✅ 案例 7:批量添加用户

bash 复制代码
#!/bin/bash
for username in user1 user2 user3
do
    id $username &> /dev/null
    if [ $? -ne 0 ]; then
        useradd -m $username
        echo "用户 $username 创建成功"
    else
        echo "用户 $username 已存在"
    fi
done

注意 :生产环境建议设置密码或使用 chpasswd

✅ 案例 8:清理过期日志文件(按天)

删除 7 天前的日志:

bash 复制代码
#!/bin/bash
for log in /var/log/app/*.log.*
do
    if [ -f "$log" ]; then
        # 获取文件修改时间距今天数
        days_old=$(( ( $(date +%s) - $(stat -c %Y "$log") ) / 86400 ))
        if [ $days_old -gt 7 ]; then
            rm -f "$log"
            echo "已删除: $log"
        fi
    fi
done

✅ 案例 9:循环执行命令并记录日志

每 5 秒监控一次系统负载:

bash 复制代码
#!/bin/bash
for (( i=1; i<=10; i++ ))
do
    load=$(uptime | awk '{print $(NF-2)}' | sed 's/,//')
    echo "$(date): 系统负载 $load" >> /tmp/monitor.log
    sleep 5
done

用途:简单性能监控脚本。

✅ 案例 10:读取文件内容逐行处理

bash 复制代码
#!/bin/bash
filename="hosts.txt"
for host in $(cat $filename)
do
    echo "正在处理: $host"
    # 示例:尝试连接
    # ping -c 1 $host &> /dev/null && echo "$host 可达"
done

⚠️ 注意 :如果文件包含空格,建议使用 while read 更安全。

更安全的写法:

bash 复制代码
while read host; do
    echo "处理: $host"
done < hosts.txt

四、常见问题与注意事项

问题 原因 解决方法
文件名含空格导致错误 for 默认按空格分割 使用 while read 或加引号
变量未定义 变量名拼写错误 使用 set -u 检查未定义变量
路径未加引号 路径含空格时报错 所有变量加双引号:"$var"
死循环 条件判断错误 仔细检查循环条件
权限不足 脚本无执行权限 chmod +x script.sh

五、for 循环优化技巧

  1. 使用 {1..10} 替代 seq 1 10:更高效,无需调用外部命令。

  2. 避免在循环中频繁调用外部命令:尽量将命令合并。

  3. 使用 &&|| 简化逻辑

    bash 复制代码
    [ -f "$file" ] && echo "存在" || echo "不存在"
  4. 结合管道与循环

    bash 复制代码
    ls *.log | while read file; do ... done

六、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
落霞的思绪31 分钟前
CSS复习
前端·css
百万蹄蹄向前冲5 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5815 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路6 小时前
GeoTools 读取影像元数据
前端
ssshooter6 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry7 小时前
Jetpack Compose 中的状态
前端
dae bal8 小时前
关于RSA和AES加密
前端·vue.js
柳杉8 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog8 小时前
低端设备加载webp ANR
前端·算法