Shell 脚本在自定义逻辑上更灵活,logrotate 在标准运维场景更稳定。如果业务日志格式特殊或需要复杂清理策略,选 Shell 脚本;如果是系统服务或标准应用日志,优先用 logrotate。风险边界在于 Shell 脚本需自行处理文件句柄释放,否则可能导致磁盘空间不释放。
先说结论:Shell 脚本适合高度定制化需求,logrotate 适合标准化自动维护,灵活性定义取决于是否接受自行维护成本。
- 适合:Shell 脚本适合非标准路径、复杂删除条件(如同时判断大小和天数)的场景。
- 重点看:logrotate 配置需关注 postrotate 脚本是否正确通知应用重置句柄。
- 别忽略:Shell 脚本删除日志前必须确认无进程占用,否则空间不会立即回收。
命令速用版
logrotate 配置示例,保留最近 3 天日志:
/var/log/myapp/*.log {
daily
rotate 3
missingok
notifempty
compress
}Shell 脚本删除 3 天前日志核心命令:
find /var/log/myapp -name "*.log" -mtime +3 -exec rm -f {} \;为什么会这样
灵活性差异源于工具设计定位不同,logrotate 是系统级标准工具,Shell 脚本是用户级自定义逻辑。logrotate 内置了状态记录、压缩、权限重置和 cron 集成,减少了重复开发成本。Shell 脚本没有固定框架,可以随意组合 find、grep、awk 等命令处理日志,但需要手动编写错误处理和定时任务。公开资料中没有看到可靠的量化数据表明哪种方式性能更高,主要区别在于维护成本和逻辑复杂度。
分步处理
使用 logrotate 配置日志切割:
1. 在/etc/logrotate.d/目录下创建新文件,例如 myapp。
2. 写入配置规则,指定日志路径、轮转周期 daily 和保留数量 rotate 3。
3. 如果应用需要信号通知,添加 postrotate 脚本段发送 HUP 信号。
4. 手动测试配置是否正确,使用命令 logrotate -d /etc/logrotate.d/myapp。
使用 Shell 脚本实现日志切割:
1. 编写脚本文件,定义日志路径 LOG_DIR 和保留天数 MAX_DAYS。
2. 使用 mv 命令重命名当前日志,使用 touch 创建新日志文件。
3. 使用 find 命令配合 -mtime 参数删除旧日志文件。
4. 赋予脚本执行权限 chmod +x,并加入 crontab 定时任务。
怎么验证是否生效
检查 logrotate 状态文件/var/lib/logrotate/status,确认最近一次轮转时间已更新。查看日志目录,确认是否存在带有日期后缀的归档文件且原日志文件大小已重置。对于 Shell 脚本,检查 cron 执行日志/var/log/cron 或脚本内部追加的运行日志,确认 find 删除命令是否按计划执行。归档文件应能正常解压查看,无损坏报错。
常见坑
直接 rm 删除正在写入的日志文件会导致磁盘空间不释放,因为进程仍持有文件句柄。logrotate 默认使用 create 模式生成新文件,比 Shell 脚本直接 mv 更安全。Shell 脚本若未处理并发执行,可能导致日志丢失或覆盖。压缩选项 compress 在 logrotate 中默认开启,Shell 脚本需手动调用 gzip 命令。
常见问题
logrotate 和 Shell 脚本能同时用吗?
不建议同时管理同一份日志,可能导致冲突或重复删除。可以选择 logrotate 管理标准日志,Shell 脚本管理特殊业务日志。
如何确保日志切割后应用继续写入?
logrotate 使用 postrotate 发送 kill -HUP 信号,Shell 脚本需在清空文件后通知应用重载配置或重启服务。
保留天数如何精确计算?
logrotate 的 rotate 参数按文件数量计算,Shell 脚本的 find -mtime 按修改时间计算,两者逻辑不同需分别测试。
参考来源
- CSDN 博客,页面标题:nginx 日志切割 (logrotate 或 shell 脚本)
- 51CTO 博客,页面标题:日志切割操作梳理 (Logrotate/python/shell 脚本实现)
- 博客园,页面标题:日志切割:logrotate、python、shell 实现