服务器运维中,日志累积会占用磁盘空间、降低检索效率,手动清理耗时且易出错。本文分享企业级Shell日志自动清理归档脚本,实现全流程自动化,适配新手入门与企业落地,同步拆解核心逻辑与部署步骤。

本文围绕需求分析、脚本实现、核心拆解、落地部署、扩展优化展开,确保脚本可直接复用,逻辑清晰易懂。

一、需求分析:明确自动化核心目标

结合运维场景,脚本需满足5大核心需求,兼顾灵活与健壮:

  • 灵活适配:自定义日志目录、归档目录,无需修改核心逻辑;

  • 精准归档:按修改时间筛选指定天数前日志,压缩留存;

  • 空间释放:自动删除过期归档文件,避免累积爆满;

  • 可追溯:记录脚本执行日志,便于异常排查;

  • 异常防护:参数校验+异常处理,避免脚本崩溃或误操作。

适配:主流Linux发行版,依赖系统自带tar、find等命令,无需额外安装。

二、完整脚本实现:可直接复制落地

脚本命名为log_auto_clean.sh,建议存放于/usr/local/shell/,关键参数可直接修改,注释清晰:

#!/bin/bash
# 脚本名称:log_auto_clean.sh
# 功能:日志自动校验、归档、过期删除,全程无人工干预
# 版本:1.0  适配:CentOS 7+/Ubuntu 18+/Debian 10+
# 日期:2026-02-09  依赖:tar、find、touch、mkdir(系统自带)

# 核心配置参数(按需修改)
LOG_DIR="/var/log/app"          # 日志源目录
ARCHIVE_DIR="/data/log_archive" # 归档目录(建议独立磁盘)
ARCHIVE_DAYS=7                  # 日志归档阈值(天)
DELETE_DAYS=30                  # 归档删除阈值(天)
SCRIPT_LOG="/var/log/log_auto_clean_script.log" # 脚本执行日志

# 日志输出函数(带时间戳、级别)
log_info() {
    local msg="$1"
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] [INFO] $msg" >> "$SCRIPT_LOG"
}

log_error() {
    local msg="$1"
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] [ERROR] $msg" >> "$SCRIPT_LOG"
    exit 1 # 非0退出,便于告警捕获
}

# 目录校验与初始化(前置检查)
check_dir() {
    if [ ! -d "$LOG_DIR" ]; then
        log_error "日志源目录 $LOG_DIR 不存在,请检查配置!"
    fi
    if [ ! -d "$ARCHIVE_DIR" ]; then
        log_info "创建归档目录 $ARCHIVE_DIR ..."
        mkdir -p "$ARCHIVE_DIR" || log_error "创建归档目录失败!"
    fi
    local script_log_dir=$(dirname "$SCRIPT_LOG")
    if [ ! -w "$script_log_dir" ]; then
        log_error "脚本日志目录无写入权限!"
    fi
}

# 日志归档(核心功能)
archive_log() {
    log_info "开始归档 $ARCHIVE_DAYS 天前的.log日志"
    find "$LOG_DIR" -type f -mtime +"$ARCHIVE_DAYS" -name "*.log" | while read -r log_file; do
        if [ -f "$log_file" ]; then
            archive_file="$ARCHIVE_DIR/$(basename "$log_file")_$(date +'%Y%m%d').tar.gz"
            tar -zcf "$archive_file" "$log_file" || log_error "压缩 $log_file 失败!"
            log_info "归档成功:$log_file -> $archive_file"
            # 可选:归档后删除原日志(取消注释启用)
            # rm -f "$log_file" && log_info "已删除原日志:$log_file"
        fi
    done
    local log_count=$(find "$LOG_DIR" -type f -mtime +"$ARCHIVE_DAYS" -name "*.log" | wc -l)
    [ "$log_count" -eq 0 ] && log_info "无符合条件日志,归档跳过"
}

# 过期归档删除(核心功能)
delete_archive() {
    log_info "开始删除 $DELETE_DAYS 天前的.tar.gz归档"
    find "$ARCHIVE_DIR" -type f -mtime +"$DELETE_DAYS" -name "*.tar.gz" -exec rm -f {} \;
    log_info "过期归档删除完成"
}

# 主执行流程
main() {
    touch "$SCRIPT_LOG" || log_error "创建脚本日志失败!"
    log_info "========== 日志自动清理归档脚本(1.0)开始执行 =========="
    check_dir
    archive_log
    delete_archive
    log_info "========== 脚本执行完成,全程无异常 ==========\n"
}

# 启动脚本
main

三、核心功能拆解:吃透设计逻辑

聚焦脚本核心设计,帮你快速理解逻辑、灵活修改,无需死记硬背。

3.1 配置参数设计

核心思路「参数与逻辑分离」,集中管理可修改项,降低维护成本:

  • LOG_DIR:日志源目录(如Nginx日志/var/log/nginx);

  • ARCHIVE_DIR:建议独立磁盘存放,避免占用系统盘;

  • ARCHIVE_DAYS:默认7天,保留近期日志便于排查;

  • DELETE_DAYS:默认30天,符合多数企业日志留存规范;

  • SCRIPT_LOG:脚本执行日志,用于异常排查。

3.2 关键函数解析

(1)日志输出函数 log_info/log_error

规范日志格式(时间戳+级别),log_error 异常时退出脚本,便于告警捕获。

(2)目录校验函数 check_dir

脚本执行前校验目录存在性、权限,归档目录不存在时自动创建,提升健壮性。

(3)日志归档函数 archive_log

核心功能:筛选指定天数前的.log文件,压缩归档,生成规范命名,避免重名。

(4)过期归档删除函数delete_archive

批量删除过期归档包,仅删除.tar.gz文件,避免误删,释放磁盘空间。

3.3 主执行流程

按「初始化日志→目录校验→日志归档→过期删除」执行,形成自动化闭环,逻辑清晰。

四、落地部署:实战步骤(新手必看)

3步部署+测试+定时配置,实现全自动化,避免踩坑。

4.1 脚本部署(3步)

# 1. 创建脚本目录
mkdir -p /usr/local/shell
# 2. 创建脚本并复制完整代码
vim /usr/local/shell/log_auto_clean.sh
# 3. 添加可执行权限
chmod +x /usr/local/shell/log_auto_clean.sh

4.2 手动测试(关键)

# 手动执行脚本
/usr/local/shell/log_auto_clean.sh
# 查看执行日志,确认正常
tail -f /var/log/log_auto_clean_script.log

测试成功:无ERROR日志,出现「执行完成」标识,归档目录有对应压缩包(如有符合条件日志)。

常见排查:权限不足(chmod 755)、目录错误、磁盘爆满(df -h)。

4.3 配置定时执行(核心)

# 编辑crontab任务
crontab -e
# 添加:每天凌晨2点执行(负载最低)
0 2 * * * /usr/local/shell/log_auto_clean.sh > /dev/null 2>&1
# 重启crontab生效(CentOS/Ubuntu分别执行)
systemctl restart crond  # CentOS
systemctl restart cron   # Ubuntu/Debian

说明:0 2 * * *为每天凌晨2点,脚本路径需写绝对路径,屏蔽无用输出。

4.4 日常监控

# 查看近期执行记录
tail -n 10 /var/log/log_auto_clean_script.log
# 检查crontab服务状态
systemctl status crond  # CentOS
systemctl status cron   # Ubuntu/Debian

五、扩展与优化:适配更多场景

基础版脚本可按需扩展,以下为4个常用方向,附核心代码片段。

5.1 多目录支持

适配多应用日志管理,将LOG_DIR改为数组,循环遍历:

LOG_DIRS=("/var/log/nginx" "/usr/local/tomcat/logs" "/var/log/mysql")
# archive_log函数中循环遍历数组,其余逻辑不变

5.2 日志大小筛选

仅归档大于指定大小的日志,避免小文件频繁归档:

# 添加-size +100M(仅归档大于100MB日志)
find "$LOG_DIR" -type f -mtime +"$ARCHIVE_DAYS" -name "*.log" -size +100M | while read -r log_file;

5.3 邮件告警

脚本失败时发送告警邮件,修改log_error函数,依赖mail命令:

ALERT_EMAIL="ops@example.com"  # 运维邮箱
log_error() {
    local msg="$1"
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] [ERROR] $msg" >> "$SCRIPT_LOG"
    echo "$msg" | mail -s "【告警】脚本执行失败" "$ALERT_EMAIL"
    exit 1
}

5.4 归档校验

校验归档包完整性,避免损坏:

tar -zcf "$archive_file" "$log_file" || log_error "压缩失败!"
# 新增校验
if ! tar -tf "$archive_file" > /dev/null 2>&1; then
    log_error "归档包 $archive_file 损坏!"
fi

六、总结

本文脚本可直接落地,核心思路为「参数化配置、分函数实现、异常处理、定时执行」,解决日志累积痛点,解放运维双手。

脚本兼具实用性与可扩展性,核心逻辑可举一反三,适配更多运维自动化场景,新手可快速上手,逐步提升自动化能力。