北屋教程网

专注编程知识分享,从入门到精通的编程学习平台

30 天 Shell 脚本修炼计划——每天一段脚本,从入门到熟练再到精通

Day-2 脚本——「轻量级日志轮转器 rotate_log.sh」

这个shell脚本与上个脚本的目录备份脚本互补:前者管整体备份,今天这个专注于单个日志文件的自动轮转、压缩和过期清理。

功能一览

  1. 按时间戳轮转:将活动日志 app.log 重命名为 app_YYYYMMDD_HHMMSS.log
  2. 自动压缩:轮转后的旧日志立即 gzip,节省磁盘
  3. 保留最新 N 份(默认 5 份),其余删除
  4. 返回码可观测:0 成功,非 0 失败,方便 cron / CI 检测


脚本源码

rotate_log.sh


#!/usr/bin/env bash

#

# rotate_log.sh — 轻量级日志轮转与保留

#

# 用法:

# ./rotate_log.sh -f /var/log/app.log [-k 5]

# 参数:

# -f 需要轮转的日志文件(必填)

# -k 最多保留轮转后的压缩包数量,默认 5

#

# 计划任务示例(每日 00:10 轮转 nginx 访问日志,保留 30 份):

# 10 0 * * * /opt/scripts/rotate_log.sh -f /var/log/nginx/access.log -k 30


set -euo pipefail


usage() {

echo "Usage: $0 -f <log_file> [-k <keep_num>]" >&2

exit 1

}


KEEP_NUM=5 # 默认保留 5 份

while getopts ":f:k:" opt; do

case "${opt}" in

f) LOG_FILE="${OPTARG}" ;;

k) KEEP_NUM="${OPTARG}" ;;

*) usage ;;

esac

done


[[ -z "${LOG_FILE:-}" ]] && usage

[[ ! -f "${LOG_FILE}" ]] && { echo "ERROR: Log file not found: ${LOG_FILE}" >&2; exit 2; }


DIR=$(dirname "${LOG_FILE}")

BASE=$(basename "${LOG_FILE}" .log) # 去掉 .log 后缀

TS=$(date '+%Y%m%d_%H%M%S')

ROTATED="${DIR}/${BASE}_${TS}.log"


echo "$(date '+%F %T') Rotate ${LOG_FILE} → ${ROTATED}"

mv "${LOG_FILE}" "${ROTATED}"


echo "$(date '+%F %T') Compress ${ROTATED}"

gzip "${ROTATED}"


# 重新创建空日志,避免应用写失败

: > "${LOG_FILE}"

chmod 644 "${LOG_FILE}"


echo "$(date '+%F %T') Cleanup: keep last ${KEEP_NUM} archives"

# 取同名 *.log.gz,按修改时间排序,超出保留数的删除

ls -1t "${DIR}/${BASE}"_*.log.gz | tail -n +"$((KEEP_NUM + 1))" | xargs -r rm -v


echo "$(date '+%F %T') Done"


落地步骤


# 1. 保存脚本

sudo mkdir -p /opt/scripts

sudo nano
/opt/scripts/rotate_log.sh # 或 vim,将上方代码粘贴


# 2. 赋权

sudo chmod +x /opt/scripts/rotate_log.sh


# 3. 立即试跑

sudo /opt/scripts/rotate_log.sh -f /var/log/syslog -k 7


# 4. 加入 crontab(示例:每天 00:05 轮转 /var/log/app.log)

crontab -e

5 0 * * * /opt/scripts/rotate_log.sh -f /var/log/app.log -k 14 >> /var/log/rotate_app.log 2>&1


关键知识点


技巧

说明

basename "$LOG_FILE" .log

去掉固定后缀,方便生成新文件名

mv && gzip

分离“轮转”和“压缩”两步,避免应用与 gzip 同时抢写

: > file

Bash 空命令,快速清空 / 新建日志文件

`ls -1t …

tail -n +N`

xargs -r rm -v

仅当有超额文件才执行删除,并逐个打印


进阶练习


  1. 信号通知:脚本结束后用 logger 写入系统日志,或调用钉钉机器人;
  2. 并行压缩:安装 pigz,替换 gzip 提升多核压缩效率;
  3. 多日志批处理:支持读取目录并对其中所有 *.log 循环调用;
  4. 完整封装为 systemd timer:替代 cron,统一管理;
  5. 单元测试:利用 Bats-core 创建旋转、保留、失败场景的自动验证。
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言