这个脚本解决什么问题?

服务器跑久了,/var/log 下的日志会无限增长。今天几个 MB,下个月几个 GB,不知不觉就把磁盘写满。磁盘满了的后果很严重:系统变慢、服务崩溃、数据写不进去,甚至整个机器卡死。

运维每天手动删日志既不现实也不安全(容易误删),所以最合理的做法是写一个脚本,让它自己判断什么该删、什么该留、怎么删才不伤服务,然后用定时任务每天自动跑。

脚本全文

用途: 自动删除超过保留天数的滚动日志,并清空过大的当前日志(保留文件句柄、无需重启服务),防止磁盘被日志堆满。

#!/bin/bash 

LOG_DIR="/var/log"
KEEP_DAY=7            # 保留天数:7 天前的旧日志就清掉

# 第一步:删除 7 天前的滚动日志
# 滚动日志形如 x.log.1、x.log.2.gz,是历史旧文件,可以放心删
find "$LOG_DIR" -name "*.log.*" -type f -mtime +"$KEEP_DAY" -exec rm -f {} \;

# 第二步:清空超大但还在用的当前日志
# 用 truncate 而不是 rm:保留文件本身,释放空间又不断服务写句柄
find "$LOG_DIR" -name "*.log" -type f -mtime +"$KEEP_DAY" -size +50M -exec truncate -s 0 {} \;

echo "[$(date '+%F %T')] 日志清理完成"

一行行看懂它

  • find "$LOG_DIR" -name "*.log.*" -type f:在日志目录里找”文件名带两个点”的这种滚动日志(xxx.log.1 这种历史文件)。
  • -mtime +7:只处理修改时间在 7 天以前的文件。
  • -exec rm -f {} \;:对每个匹配到的文件执行删除。
  • 第二步里的 truncate -s 0:把文件内容清空但保留文件本身。这是关键细节——如果直接 rm 正在被服务写的日志,文件句柄还占着,磁盘空间不会真正释放;truncate 既释放了空间,又让服务能继续写,还不用重启。

怎么用

vim clean_log.sh        # 把上面脚本贴进去保存
chmod +x clean_log.sh   # 加执行权限
./clean_log.sh          # 手动跑一次看效果
crontab -e              # 再配定时,每天凌晨 2 点自动跑
# 加入这一行:
0 2 * * * /root/scripts/clean_log.sh

常见坑

现象原因解决
Permission denied没加执行权限chmod +x clean_log.sh
提示找不到文件路径用了相对路径脚本里路径写绝对,例如 /var/log
日志没被删时间条件不对先 find /var/log -name "*.log.*" 看文件时间,再调 KEEP_DAY

小结

清理日志的核心不是”删文件”,而是“只删该删的、删的时候不伤服务”。find 负责精准挑选,-mtime 负责控制时间,truncate 负责安全释放。这一个脚本,配合 crontab,就能让你再也不用担心”磁盘半夜满了”。