如何实现后台运行的Bash脚本日志文件按日轮转?
解决Bash服务脚本按日生成日志的问题
问题根源
你的脚本里的date "+%Y_%m_%d"只在脚本启动瞬间执行一次,之后日期变更时不会重新计算文件名,所以日志始终写入启动当天的文件。
解决方案
方法1:用logrotate(推荐,系统级日志管理)
这是Linux自带的成熟日志轮转工具,配置简单且稳定,适合长期运行的服务。
- 创建
logrotate配置文件,比如/etc/logrotate.d/process_log:
/path/to/process_*.log { daily rotate 30 copytruncate missingok notifempty dateext dateformat _%Y_%m_%d }
daily:按天轮转日志rotate 30:保留最近30天的旧日志copytruncate:复制当前日志内容到新文件后清空原文件,无需重启服务dateext:用日期作为旧日志的后缀,和你的命名格式匹配dateformat:指定日期格式,和你现有文件名一致
- 测试配置(不会实际修改文件):
logrotate -d /etc/logrotate.d/process_log
- 系统默认的
cron任务会每日自动执行logrotate,无需额外配置(可检查/etc/cron.daily/logrotate确认)
方法2:修改脚本动态切换日志文件
如果不想依赖系统工具,直接修改Process.sh实现每日切分:
方案A:自定义日志函数
#!/bin/bash set -x # 定义日志输出函数,自动写入当日文件 log_daily() { while IFS= read -r line; do local log_file="process_$(date "+%Y_%m_%d").log" echo "$line" >> "$log_file" echo "$line" # 同步输出到终端(可选) done } ( # 这里放你原来的脚本逻辑 .. ... ... ) 2>&1 | log_daily
每次输出内容时,都会先获取当前日期,写入对应的日志文件,日期变更时自动切换新文件。
方案B:用awk处理日志切分
#!/bin/bash set -x ( # 原脚本逻辑 .. ... ... ) 2>&1 | awk '{ curr_date=strftime("%Y_%m_%d") log_file="process_" curr_date ".log" print >> log_file close(log_file) # 防止文件句柄泄漏 print # 同步输出到终端(可选) }'
awk会在每一行输出时检查当前日期,自动切换到当日日志文件,无需额外逻辑。
注意事项
- 方法2依赖脚本运行期间系统时间正常,避免日期跳变导致日志混乱。
- 生产环境优先选方法1,
logrotate能自动处理日志压缩、过期清理,减少维护工作量。
内容的提问来源于stack exchange,提问作者Miss aya
相关产品推荐
相关产品推荐

