前言
在服务器运维中,日志文件(Logs) 是个让人又爱又恨的东西。 爱它是因为出了Bug全靠它排查;恨它是因为它每天疯狂增长,如果不定期清理,很快就会把服务器磁盘塞满(Disk Full),导致服务宕机。
很多新手是等到磁盘满了,才急匆匆地上去手动删除。今天,我们用一个简单的 Shell 脚本,配合 Linux 的定时任务,把“备份日志”和“清理旧日志”这件事彻底自动化。
场景描述
假设我们的应用日志放在 /data/logs/myapp/ 目录下。我们的目标:
- 每天凌晨2点,把昨天的日志打包压缩。
- 将压缩包移动到备份目录
/data/backup/。 - 自动删除 7 天前的备份文件,节省空间。
第一步:编写脚本 (backup_logs.sh)
首先,创建一个脚本文件:
Bash
vim backup_logs.sh
然后,复制以下代码。我已经给每一步都加了详细的中文注释,确保你能看懂。
Bash
#!/bin/bash # ================= 配置区域 ================= # 日志源目录 SOURCE_DIR="/data/logs/myapp" # 备份存放目录 BACKUP_DIR="/data/backup/myapp" # 获取当前日期,格式如:20231027 DATE=$(date +%Y%m%d) # =========================================== # 1. 判断备份目录是否存在,不存在则创建 if [ ! -d "$BACKUP_DIR" ]; then mkdir -p "$BACKUP_DIR" echo "创建备份目录: $BACKUP_DIR" fi # 2. 开始打包压缩 # 将源目录下的所有 .log 文件打包成 log_日期.tar.gz echo "开始备份..." tar -czf "$BACKUP_DIR/log_$DATE.tar.gz" "$SOURCE_DIR"/*.log # 检查上一条命令是否执行成功 if [ $? -eq 0 ]; then echo "备份成功:$BACKUP_DIR/log_$DATE.tar.gz" else echo "备份失败!请检查目录或权限。" exit 1 fi # 3. 清理旧日志 # 找到备份目录下,超过7天(+7)且后缀为 .tar.gz 的文件,并执行删除 find "$BACKUP_DIR" -type f -mtime +7 -name "*.tar.gz" -exec rm -rf {} \; echo "已清理7天前的旧备份文件。" echo "任务完成。"
第二步:赋予执行权限
还记得上一篇讲的 chmod 吗?刚写好的脚本是没有执行权限的。
Bash
# 赋予脚本执行权限 chmod +x backup_logs.sh
建议: 在正式上定时任务前,先手动运行一次脚本 ./backup_logs.sh,看看有没有报错,备份目录下有没有生成压缩文件。
第三步:设置定时任务 (Crontab)
脚本写好了,我们不能每天半夜爬起来手动点一下。Linux 自带的 Crontab 是最好的定时器。
- 打开定时任务编辑器:
Bash
crontab -e
- 在编辑器末尾添加一行(按
i进入编辑模式):Bash
# 每天凌晨 02:00 执行备份脚本 0 2 * * * /root/scripts/backup_logs.sh >> /tmp/backup.log 2>&1
- 这行代码的含义:
0 2 * * *:分 时 日 月 周。意思是每天的 02:00 执行。/root/scripts/backup_logs.sh:脚本的绝对路径(注意:一定要用绝对路径!)。>> /tmp/backup.log 2>&1:把脚本执行过程中的输出日志(包括正确输出和错误报错)都记录到/tmp/backup.log里,方便后续排查脚本是否执行成功。
- 保存退出(按
Esc,输入:wq)。
第四步:验证定时任务
如何确认定时任务是否生效了?
Bash
# 查看当前用户的定时任务列表 crontab -l # 查看系统定时任务日志(查看是否有执行记录) tail -f /var/log/cron
总结
通过这个简单的脚本,我们实现了一个闭环的自动化运维流程:自动备份 -> 自动压缩 -> 自动清理过期文件。
虽然现在的云服务提供了很多现成的日志服务(如阿里云SLS),但掌握这种基础的 Shell 脚本编写能力,能让你在处理一些临时性、定制化的任务时游刃有余。
小作业:尝试修改脚本,将“保留7天”改为“保留30天”,你知道该改哪一行吗?