从运维小白到自动清理高手的完整指南
目录导读
为什么你的服务器需要定时删除过期日志?
日志文件是系统运行的重要记录,但如果不加管理,它们会像“数据垃圾”一样迅速膨胀,在实际运维中,我们经常遇到以下场景:

- 某天磁盘告警,发现
/var/log/占用超过80%的磁盘空间 - 应用日志每天增长500MB,45天后导致
/home/分区爆满 - 审计要求的日志保留30天,但手动删除又繁琐又容易误删
当你使用一个 定时删除过期日志的脚本 后,所有问题都会迎刃而解,该脚本的核心价值在于:
- 自动清理:无需人工介入,自动查找并删除超过指定天数的日志文件
- 节省磁盘:彻底避免“日志撑爆硬盘”导致服务中断的悲剧
- 合规保留:精准控制日志保留期限(如30天、60天、180天)
一个真实的案例:某电商公司线上服务器因为日志一个月未清理,导致磁盘写满,最终数据库宕机2小时,事后他们紧急部署了定时删除过期日志的脚本,至今未再出现同类事故。
定时删除日志脚本的核心原理
要编写一个强大的日志清理脚本,你需要理解三个核心元素:
文件时间戳识别
Linux系统中,每个文件有三个时间戳:
mtime(修改时间):文件内容最后被修改的时间ctime(状态更改时间):文件权限或属性发生变化的时间atime(访问时间):文件最后被读取的时间
对于日志文件,我们通常基于 mtime 判断是否过期。
查找并匹配目标文件
使用 find 命令是脚本的关键。
find /var/log/ -name "*.log" -type f -mtime +30
这表示:在 /var/log/ 下查找所有以 .log 且最后修改时间超过30天的普通文件。
删除或压缩操作
找到文件后,你可以选择:
- 直接删除:
-delete或exec rm -f {} \; - 压缩归档:用
gzip压缩后删除源文件,保留.gz压缩包 - 移至备份目录:配合
mv命令实现“软删除”
手写一个完整的定时删除日志脚本(附代码)
以下是一个可直接部署的 bash 脚本,功能包括:
- 自定义要清理的目录
- 自定义保留天数
- 支持白名单(跳过重要日志)
- 生成清理日志,方便审计
脚本文件名:clean_expired_logs.sh
#!/bin/bash
# 配置区 —— 根据你的实际环境修改以下变量
LOG_DIRS=("/var/log" "/home/app/logs" "/data/wwwlogs") # 要清理的日志目录
RETENTION_DAYS=30 # 保留天数(例如30天)
EXCLUDED_PATTERNS=("*.gz" "important.log") # 不删除的文件模式(白名单)
SCRIPT_LOG="/var/log/log_cleaner.log" # 脚本自身的运行日志
# 函数:输出带时间戳的日志
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "${SCRIPT_LOG}"
}
# 开始清理
log "========== 定时删除过期日志脚本开始运行 =========="
for dir in "${LOG_DIRS[@]}"; do
if [ ! -d "$dir" ]; then
log "目录 [${dir}] 不存在,跳过"
continue
fi
log "正在扫描目录: ${dir}"
# 构建排除参数(跳过白名单文件)
exclude_opts=""
for pattern in "${EXCLUDED_PATTERNS[@]}"; do
exclude_opts="${exclude_opts} -not -name \"${pattern}\""
done
# 查找并删除超过保留天数的日志文件
find "$dir" -type f \( -name "*.log" -o -name "*.txt" \) \
-mtime +${RETENTION_DAYS} \
${exclude_opts} \
-exec rm -f {} \; \
-print | while read deleted_file; do
log "已删除过期日志: ${deleted_file}"
done
# 可选:同时删除空的日志目录(如果结构允许)
find "$dir" -type d -empty -delete 2>/dev/null
done
log "========== 定时删除过期日志脚本运行完成 =========="
log ""
如何使用这个脚本?
- 保存脚本:将上述内容保存为
/usr/local/bin/clean_expired_logs.sh - 赋予执行权限:
chmod +x /usr/local/bin/clean_expired_logs.sh - 首次测试运行:
/usr/local/bin/clean_expired_logs.sh - 查看运行日志:
tail -f /var/log/log_cleaner.log
如何用crontab实现自动化运行
仅仅写好脚本还不够,你需要让系统定时自动执行,Linux 的 crontab 是最好的选择。
步骤1:编辑 crontab 任务
执行命令:crontab -e
步骤2:添加定时任务
以下是一些常用配置:
# 每天凌晨2点执行一次 0 2 * * * /usr/local/bin/clean_expired_logs.sh # 每天凌晨3点半执行(避开高峰期) 30 3 * * * /usr/local/bin/clean_expired_logs.sh # 每10天执行一次(低频场景) 0 0 */10 * * /usr/local/bin/clean_expired_logs.sh
步骤3:验证定时任务
- 查看已添加的任务:
crontab -l - 查看 cron 服务是否运行:
systemctl status crond或service cron status - 查看脚本执行日志:
tail -f /var/log/log_cleaner.log
执行频率建议:对于日志量较大的生产服务器,建议每天执行一次,保留天数设为 30~60 天,对于日志量较小的测试服务器,可以每周或每两周执行一次。
常见问题问答(FAQ)
问1:这个脚本会不会误删正在写入的日志文件?
答:一般不会。 因为脚本基于 mtime(最后修改时间)判断,正在写入的日志文件,其 mtime 会持续更新,只要保留天数设置合理(如30天),就不会误删当前正在使用的文件,如果担心,可以增加 -not -name "access.log" 等白名单。
问2:我想保留某些特定的日志文件,怎么办?
答:使用脚本中的 EXCLUDED_PATTERNS 数组。
EXCLUDED_PATTERNS=("*.gz" "audit.log" "security.log")
这样所有 *.gz 压缩文件以及名为 audit.log security.log 的文件都会被跳过。
问3:脚本在Windows上能用吗?
答:不能直接使用。 本脚本基于 bash 和 Linux 命令,Windows环境你需要使用 PowerShell 脚本,类似这样:
Get-ChildItem -Path "C:\Logs" -Filter "*.log" | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} | Remove-Item
然后用 Windows 任务计划程序设定定时执行。
问4:我每天生成的日志很大,保留30天但依然不够?
答:可以考虑“压缩+删除”模式。 先将超过7天的日志压缩为 .gz,再删除超过30天的 .gz 文件,这样即节省空间,又满足审计需要,脚本改造如下:
# 压缩超过7但小于30天的日志
find /var/log -name "*.log" -type f -mtime +7 -mtime -30 -exec gzip {} \;
# 删除超过30天的所有日志(包括压缩包)
find /var/log -type f \( -name "*.log" -o -name "*.gz" \) -mtime +30 -exec rm -f {} \;
问5:如何让脚本只删除而不打印大段输出?
答:将标准输出重定向到 /dev/null。 在 cron 任务中配置:
0 2 * * * /usr/local/bin/clean_expired_logs.sh > /dev/null 2>&1
这样不会有任何输出被发送到邮箱,但你仍然可以在 ${SCRIPT_LOG} 中看到详细日志。
脚本优化与安全注意事项
细颗粒度优化
- 按日期分目录存储:让你的日志系统每天生成独立的目录(如
logs/2025-01-15/),脚本就可以直接删除整个过期目录,效率翻倍 - 保留最后N个文件:如果你不希望依据天数,而是想保留最近100个文件,可以使用
ls -1t | tail -n +101配合rm - 发送报警通知:当删除的文件数量超过阈值(比如一次删除了1000个文件),利用
mail或curl发送告警给运维人员
安全红线(务必遵守)
- 永远先测试再上线:先在测试环境运行脚本,用
-print代替-exec rm查看哪些文件会被删除 - 留意别的应用:确认目标目录中没有其他应用的重要数据文件(
.dat,.json等非日志文件) - 尽量使用绝对路径:无论是目录、日志文件、脚本路径,都用绝对路径,避免 cron 的环境变量问题
- 小心符号链接:
find的-type f可以避免误删链接指向的外部文件
更专业的替代方案
如果你觉得手动维护脚本太麻烦,可以考虑以下企业级方案:
- logrotate:Linux 自带的日志轮转工具,支持压缩、轮转天数、保留数量
- ELK + Curator:在 Elasticsearch 端自动管理索引生命周期
- 商业监控软件:如 Zabbix、Nagios 自带的日志清理功能
通过以上完整的学习,你已经掌握了从编写、测试到部署定时删除过期日志的脚本的全流程,无论是面对500G的日志洪流,还是遇到磁盘告警,这套方案都能让你成为“自动清理高手”,现在就动手在你的服务器上实践一下吧!