Shell脚本批量运维实战案例:从零实现服务器批量巡检与修复
为什么要掌握Shell脚本批量运维
日常运维中,经常需要对几十甚至上百台服务器执行相同的操作,比如检查磁盘空间、更新软件包、重启某个服务。
如果一台一台登录执行,效率极低且容易遗漏。Shell脚本批量运维可以一次性把命令发送到所有目标机器,并收集结果,大幅提升效率。
本文以一个真实的“批量巡检磁盘使用率并自动清理临时文件”案例为主线,带你走通从0到1的全过程。
前置准备:环境与权限
- 准备一个中控机:任意一台Linux机器(例如你的笔记本或跳板机)。
- 收集目标服务器IP列表:创建一个纯文本文件
/root/server_list.txt,每行一个IP地址:
192.168.1.10
192.168.1.11
192.168.1.12
- 配置SSH免密登录:在中控机上生成密钥对(已有可跳过),然后将公钥分发到所有目标服务器:
ssh-keygen -t rsa -b 2048 -N '' -f ~/.ssh/id_rsa
for ip in $(cat /root/server_list.txt); do ssh-copy-id root@$ip; done
如果目标服务器密码不一致,可以先用 sshpass 或先手动分发一次,后续操作就无需密码了。
编写批量巡检脚本:从单机到批量
我们创建一个脚本 /root/disk_check.sh,包含功能:检查每个服务器的磁盘使用率,若超过80%则列出 /tmp 下大于100MB的文件并删除。
#!/bin/bash
# 定义变量
IP_LIST="/root/server_list.txt"
THRESHOLD=80
CLEAN_DIR="/tmp"
RESULT_LOG="/root/disk_check_result_$(date +%Y%m%d).log"
# 清空上次结果
echo "" > $RESULT_LOG
# 循环遍历每个IP
while read ip; do
echo "========== $ip ==========" >> $RESULT_LOG
# 获取磁盘使用率(取根分区的 Use% 数字部分)
usage=$(ssh root@$ip "df / | grep -v Filesystem | awk '{print \$5}' | sed 's/%//'")
if [ $? -ne 0 ]; then
echo "连接失败或命令执行错误" >> $RESULT_LOG
continue
fi
if [ "$usage" -gt $THRESHOLD ]; then
echo "磁盘使用率 $usage% 超过阈值 $THRESHOLD%,开始清理..." >> $RESULT_LOG
# 列出 /tmp 下大于100MB的文件
big_files=$(ssh root@$ip "find $CLEAN_DIR -type f -size +100M -exec ls -lh {} \;")
if [ -n "$big_files" ]; then
echo "发现大文件:" >> $RESULT_LOG
echo "$big_files" >> $RESULT_LOG
# 删除这些文件(注意:生产环境请确认再删除)
ssh root@$ip "find $CLEAN_DIR -type f -size +100M -delete" && echo "已删除大文件" >> $RESULT_LOG
else
echo "未找到超过100M的大文件,请手动检查" >> $RESULT_LOG
fi
else
echo "磁盘使用率 $usage%,正常" >> $RESULT_LOG
fi
echo "" >> $RESULT_LOG
done < "$IP_LIST"
给脚本执行权限并运行:
chmod +x /root/disk_check.sh
bash /root/disk_check.sh
避坑指南:批量运维常见问题
- SSH超时或连接中断:在脚本中建议增加连接超时参数
-o ConnectTimeout=5,避免因某台机器不可达导致脚本卡死。例如:ssh -o ConnectTimeout=5 root@$ip "command"。 - 目标服务器命令差异:不同发行版的
df输出可能略有不同,建议先在单台测试再放到循环中。可以在脚本开头加入set -e让错误立即终止,也可以自己加更严格的管道处理。 - 删除操作要谨慎:示例中直接
-delete删除了临时文件,线上环境建议先只用-print列出,确认无误后再删除。可以在脚本里加一个变量DRY_RUN=true,当为true时只列出不删除。 - 日志覆盖:脚本里每天生成一个新日志文件,不会覆盖历史记录,方便追溯。
- 并发执行优化:如果服务器数量很多(超过20台),上述串行循环会很慢,可以考虑用
parallel或后台进程池并行执行,但新手建议先用串行,确保正确后再优化。
验证效果与后续扩展
执行脚本后,查看 /root/disk_check_result_20250325.log(以当天日期为例),内容类似:
========== 192.168.1.10 ==========
磁盘使用率 85% 超过阈值 80%,开始清理...
发现大文件:
-rw-r--r-- 1 root root 200M Mar 20 10:00 /tmp/old_log.tar.gz
已删除大文件
========== 192.168.1.11 ==========
磁盘使用率 45%,正常
即表示成功。
扩展思路:
- 可以改为巡检内存、CPU负载、进程数量等,只需修改远程命令。
- 将脚本加入crontab每天定时执行,实现自动化运维。
- 如果想让脚本更健壮,可以加入邮件或钉钉通知,把每次的异常结果发送给管理员。
如果你正在处理Shell脚本批量运维实战案例,建议先按本文步骤完整执行,再根据自己的环境做微调;
遇到异常时优先回看避坑和高频问题部分。