通过编写shell脚本可实现linux多目录日志的灵活切割与归档,1. 明确需处理的日志目录、切割周期(如按天)、保留份数(如7天)、是否压缩等需求;2. 编写脚本遍历指定日志目录,对*.log文件按日期重命名并移动,清空原文件以保持服务写入,随后压缩归档并清理过期日志;3. 配置cron定时任务每天凌晨执行脚本,确保自动化运行;4. 注意文件权限、服务重载(如nginx -s reopen)及避免业务高峰操作,提升稳定性和兼容性。

linux系统中日志文件会随着时间不断增长,若不及时处理,可能占用大量磁盘空间甚至影响服务运行。虽然logrotate是标准的日志切割工具,但在多目录、自定义命名或特殊业务场景下,使用自定义脚本进行日志切割和分类管理更为灵活高效。下面介绍如何通过编写Shell脚本实现多目录日志的自动切割与归档。
1. 明确日志切割目标
在编写脚本前,先确定需求:
例如:每天凌晨对多个应用日志目录进行切割,保留最近7天的日志,旧日志以日期命名并压缩。
2. 编写自定义日志切割脚本
创建一个Shell脚本,例如 /opt/scripts/cut_logs.sh:
!/bin/bash
日志根目录数组
LOG_DIRS=( “/var/log/app1” “/var/log/app2” “/var/log/myapp” )
获取昨天的日期(用于日志命名)
date=$(date -d “yesterday” +%Y%m%d)
DATE=$(date +%Y%m%d_%H%M) # 按小时切割可用此格式
循环处理每个日志目录
for LOG_DIR in “${LOG_DIRS[@]}”; do
判断目录是否存在
if [ ! -d "$LOG_DIR" ]; then echo "目录不存在: $LOG_DIR" continue fi # 进入日志目录 cd "$LOG_DIR" || continue # 查找所有 .log 结尾的文件进行切割 for log_file in *.log; do # 确保文件存在且非空 if [ -f "$log_file" ] && [ -s "$log_file" ]; then # 构造新文件名:原名 + 日期 new_name="${log_file%.*}_${DATE}.log" # 移动当前日志并清空原文件 mv "$log_file" "$new_name" > "$log_file" # 清空原文件 # 压缩归档(可选) gzip "$new_name" echo "已切割: $LOG_DIR/$new_name.gz" fi done
done
可选:删除7天前的压缩日志
find /var/log -name “*.gz” -type f -mtime +7 –delete
该脚本支持多个日志目录,自动按日期重命名日志,并清空原始文件避免重启服务。压缩后通过find命令定期清理老旧日志。
3. 设置定时任务自动执行
使用crontab让脚本每天自动运行:
运行命令:
crontab -e
添加以下行(每天凌晨1点执行):
0 1 * * * /bin/bash /opt/scripts/cut_logs.sh >> /var/log/log_cut.log 2>&1
确保脚本有执行权限:
chmod +x /opt/scripts/cut_logs.sh
4. 注意事项与优化建议
实际使用中需注意以下几点:
- 确保应用对日志文件有写权限,清空文件不会导致写入失败
- 某些服务需重新加载(如nginx -s reopen)才能继续写入原文件,可在脚本中加入reload命令
- 可根据需要增加邮件通知功能(如用mail命令发送摘要)
- 生产环境建议先在测试目录验证脚本逻辑
- 避免在业务高峰期执行切割操作
基本上就这些。通过自定义脚本,你可以灵活控制日志切割策略,适应复杂目录结构和业务需求,比单纯依赖logrotate更可控。关键是理解mv + 清空的机制,并结合cron实现自动化。不复杂但容易忽略权限和应用兼容性问题。