服务器磁盘自动清理

📁 先看这个:本文会创建哪些文件(名字统一)

  • /etc/disk-auto-clean.env:配置文件(Token、频道ID、阈值、日报时间)
  • /usr/local/bin/disk-auto-clean.sh:主执行脚本(自动清理/失败告警/日报)
  • /var/lib/disk-auto-clean/state.log:运行记录文件(脚本自动生成)

后续所有命令都只用同一个脚本名:/usr/local/bin/disk-auto-clean.sh

🚀 新手最短路径(先跑通)

  1. 先创建配置文件:/etc/disk-auto-clean.env
  2. 再创建脚本文件:/usr/local/bin/disk-auto-clean.sh
  3. 给脚本执行权限:chmod +x /usr/local/bin/disk-auto-clean.sh
  4. 手动测试:/usr/local/bin/disk-auto-clean.sh --force
  5. 加定时任务:每10分钟执行一次同一个脚本

这是一篇给新手小白的完整实战教程。目标是:当磁盘占用超过阈值时自动清理,并推送Telegram通知;同时支持系统自动识别(Debian/Ubuntu/CentOS)、清理失败告警、每日汇总报告。


📌 你将得到什么

  • 自动识别系统并执行对应清理命令
  • 磁盘占用超过阈值(默认88%)自动清理
  • 清理成功/失败都会推送Telegram
  • 每天固定时间推送“日报”
  • 通知使用中文,且不显示公网IP/主机名

🧰 准备工作

先确认这4件事(不会就照着做):

  1. 你是 root 用户(或命令前加 sudo
  2. 系统时间正确:执行 date 看时间是否正常
  3. 服务器能上外网:执行 curl -I https://api.telegram.org
  4. Telegram 机器人已经被拉进你的频道
  1. 一台Linux服务器(Debian/Ubuntu/CentOS/Rocky/AlmaLinux均可)
  2. root权限
  3. Telegram Bot Token
  4. Telegram频道Chat ID(通常是 -100xxxxxxxxxx
  5. Bot已加入频道并有发消息权限

① 创建配置文件

本步骤创建的文件:/etc/disk-auto-clean.env
说明:保存 Telegram Token、频道ID、阈值、日报时间,后续脚本会读取它。

cat > /etc/disk-auto-clean.env <<'EOF'
TG_BOT_TOKEN="你的BotToken"
TG_CHAT_ID="-100xxxxxxxxxx"
THRESHOLD="88"
REPORT_HOUR="21"
REPORT_MIN="00"
EOF
chmod 600 /etc/disk-auto-clean.env

参数说明:

• TG_BOT_TOKEN:你的 Telegram 机器人“密码钥匙”
• TG_CHAT_ID:消息要发到哪个频道/群(地址ID)
• THRESHOLD=”88″:磁盘用到 88% 就触发清理
• REPORT_HOUR=”21″:每天 21点
• REPORT_MIN=”00″:每天 00分

② 安装主脚本(自动识别系统 + 失败告警)

本步骤创建的文件:/usr/local/bin/disk-auto-clean.sh
说明:核心执行脚本(自动清理、失败告警、日报)。后面所有运行命令都调用这个文件。

cat > /usr/local/bin/disk-auto-clean.sh <"$LOCK_FILE"
flock -n 9 || exit 0

ENV_FILE="/etc/disk-auto-clean.env"
[[ -f "$ENV_FILE" ]] || exit 1
source "$ENV_FILE"

THRESHOLD="${THRESHOLD:-88}"
FORCE="${1:-}"
MODE="${2:-auto}"   # auto | report
NOW="$(date '+%F %T %Z')"
STATE_DIR="/var/lib/disk-auto-clean"
STATE_FILE="$STATE_DIR/state.log"
mkdir -p "$STATE_DIR"

usage_now(){ df -P / | awk 'NR==2{gsub(/%/,"",$5);print $5}'; }
root_df(){ df -h / | awk 'NR==2{print $2" 总计,已用 "$3",可用 "$4"("$5")"}'; }

send_tg(){
  local msg="$1"
  curl -sS -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" 
    -d chat_id="${TG_CHAT_ID}" -d parse_mode="HTML" 
    --data-urlencode text="$msg" -d disable_web_page_preview=true >/dev/null || true
}

get_location_cn(){
  local j c r ci
  j="$(curl -fsS --max-time 6 https://ipwho.is/ 2>/dev/null || true)"
  if [[ -n "$j" ]]; then
    c="$(echo "$j"|sed -n 's/.*"country":"([^"]*)".*/1/p'|head -n1)"
    r="$(echo "$j"|sed -n 's/.*"region":"([^"]*)".*/1/p'|head -n1)"
    ci="$(echo "$j"|sed -n 's/.*"city":"([^"]*)".*/1/p'|head -n1)"
    [[ "$c" == "Macao" || "$c" == "Macau" ]] && c="中国澳门"
    [[ "$c" == "Hong Kong" ]] && c="中国香港"
    [[ "$c" == "Japan" ]] && c="日本"
    [[ "$c" == "United States" ]] && c="美国"
    [[ "$c" == "Singapore" ]] && c="新加坡"
    echo "${c:-未知} / ${r:-未知} / ${ci:-未知}"; return
  fi
  echo "未知 / 未知 / 未知"
}

clean_cache_by_os(){
  local ok=0
  if command -v apt-get >/dev/null 2>&1; then
    apt-get clean >/dev/null 2>&1 || true
    rm -rf /var/lib/apt/lists/* >/dev/null 2>&1 || true
    ok=1
  fi
  if command -v dnf >/dev/null 2>&1; then
    dnf clean all >/dev/null 2>&1 || true
    ok=1
  fi
  if command -v yum >/dev/null 2>&1; then
    yum clean all >/dev/null 2>&1 || true
    ok=1
  fi
  return $ok
}

daily_report(){
  local total=0 success=0 fail=0 last='无'
  [[ -f "$STATE_FILE" ]] && {
    total=$(grep -c '^RUN|' "$STATE_FILE" || true)
    success=$(grep -c '^OK|' "$STATE_FILE" || true)
    fail=$(grep -c '^FAIL|' "$STATE_FILE" || true)
    last=$(tail -n1 "$STATE_FILE" | cut -d'|' -f2- || echo '无')
  }
  send_tg "📘 每日磁盘清理汇总
日期:$(date +%F)
地区:$(get_location_cn)
今日执行:${total} 次
成功:${success} 次
失败:${fail} 次
当前磁盘:$(root_df)
最近记录:${last}"
}

if [[ "$MODE" == "report" ]]; then
  daily_report
  exit 0
fi

before_use="$(usage_now)"
before_df="$(root_df)"
[[ "$FORCE" != "--force" && "$before_use" -lt "$THRESHOLD" ]] && exit 0

echo "RUN|$NOW|before=${before_use}%" >> "$STATE_FILE"

err=""
{
  clean_cache_by_os || true
  find /tmp -mindepth 1 -mtime +3 -delete >/dev/null 2>&1 || true
  find /var/tmp -mindepth 1 -mtime +3 -delete >/dev/null 2>&1 || true
  docker image prune -a -f >/dev/null 2>&1 || true
  docker builder prune -a -f >/dev/null 2>&1 || true
} || err="清理命令执行异常"

after_use="$(usage_now)"
after_df="$(root_df)"
delta=$((before_use-after_use))

if [[ -n "$err" ]]; then
  echo "FAIL|$NOW|$err" >> "$STATE_FILE"
  send_tg "❌ 磁盘自动清理失败告警
时间:$NOW
地区:$(get_location_cn)
触发阈值:${THRESHOLD}%
清理前:$before_df
当前:$after_df
错误:$err"
  exit 1
fi

echo "OK|$NOW|${before_use}%->${after_use}%" >> "$STATE_FILE"
send_tg "🧹 磁盘自动清理通知
地区:$(get_location_cn)
时间:$NOW
触发阈值:${THRESHOLD}%

清理结果
• 清理前:$before_df
• 清理后:$after_df
• 占用变化:${before_use}% → ${after_use}%(下降 ${delta}%)"
EOF

chmod +x /usr/local/bin/disk-auto-clean.sh

③ 配置定时任务(自动清理 + 每日汇总)

本步骤修改的内容:crontab(系统定时任务表,不是脚本文件本体)

先理解这两个文件的分工:

  • /usr/local/bin/disk-auto-clean.sh:真正执行清理/告警/日报的脚本(“做事的人”)
  • crontab:定时器(“叫脚本按时上班的人”)

所以你要改“多久执行一次”,改的是 crontab,不是改脚本文件名。

操作步骤(小白版):

  1. 执行 crontab -e 打开定时任务编辑器(文件一般所在位置/bin/nano)
  2. 把下面两行粘贴进去(有重复就保留一份)
  3. 保存并退出(生效)
  4. 执行 crontab -l 检查是否写入成功
*/10 * * * * /usr/local/bin/disk-auto-clean.sh
00 21 * * * /usr/local/bin/disk-auto-clean.sh --force report
这两行是什么意思?

  • */10 * * * *:每10分钟执行一次“自动清理检测”
  • 00 21 * * *:每天 21:00 执行一次“每日汇总”

如果你想改频率:比如每30分钟,把第一行改成 */30 * * * * 即可。

本步骤修改的文件:当前用户 crontab(系统定时任务表)
一句话理解:就是让服务器“自己按时间执行脚本”,你不用手动去敲命令。

小白解释:

  • */10 * * * * = 每10分钟执行一次
  • 21:00 的日报 = 每天晚上9点自动发一条汇总
  • crontab -l = 查看当前定时任务是否生效

n

本步骤修改的文件:当前用户 crontab(系统内部定时任务表)
说明:添加两条任务:每10分钟清理检查、每天固定时间日报。

# 每10分钟检查一次
( crontab -l 2>/dev/null | grep -v '/usr/local/bin/disk-auto-clean.sh' || true; 
  echo '*/10 * * * * /usr/local/bin/disk-auto-clean.sh' ) | crontab -

# 每日汇总(默认21:00)
source /etc/disk-auto-clean.env
( crontab -l 2>/dev/null | grep -v 'disk-auto-clean.sh --force report' || true; 
  echo "${REPORT_MIN:-00} ${REPORT_HOUR:-21} * * * /usr/local/bin/disk-auto-clean.sh --force report" ) | crontab -

crontab -l

④ 手动测试(强烈建议)

本步骤运行的文件:/usr/local/bin/disk-auto-clean.sh
目的:先人工跑一遍,确认“脚本能执行 + Telegram能收到消息”。

你会看到什么才算成功?

  1. 命令执行后没有报错(返回命令行)
  2. Telegram频道收到“磁盘自动清理通知”或“每日汇总”
  3. 可选检查:tail -n 20 /var/lib/disk-auto-clean/state.log 能看到 OK 记录

如果失败怎么办?

  • 先检查 Bot 是否在频道里
  • 再检查 /etc/disk-auto-clean.env 里的 Token/ChatID 是否正确
  • 再执行:bash -x /usr/local/bin/disk-auto-clean.sh --force 看具体报错

n

本步骤运行的文件:/usr/local/bin/disk-auto-clean.sh
可能生成/更新的文件:/var/lib/disk-auto-clean/state.log(运行记录)

# 测试清理通知
/usr/local/bin/disk-auto-clean.sh --force

# 测试每日汇总
/usr/local/bin/disk-auto-clean.sh --force report

🧪 排错指南(小白版)

n

本步骤重点查看文件:/var/lib/disk-auto-clean/state.log
说明:这里记录每次执行的成功/失败状态和时间。

  • 收不到消息:先确认bot在频道里且有发言权限
  • 清理无明显变化:多半是业务数据本体占空间,不是缓存
  • CentOS没反应:检查 yum/dnf 是否存在,脚本已自动识别
  • 看执行记录:tail -n 30 /var/lib/disk-auto-clean/state.log

🔁 回滚/卸载方法

本步骤会删除/修改:crontab/usr/local/bin/disk-auto-clean.sh/etc/disk-auto-clean.env/var/lib/disk-auto-clean/

crontab -l | grep -v 'disk-auto-clean.sh' | crontab -
rm -f /usr/local/bin/disk-auto-clean.sh
rm -f /etc/disk-auto-clean.env
rm -rf /var/lib/disk-auto-clean
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇