📁 先看这个:本文会创建哪些文件(名字统一)
/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
🚀 新手最短路径(先跑通)
- 先创建配置文件:
/etc/disk-auto-clean.env - 再创建脚本文件:
/usr/local/bin/disk-auto-clean.sh - 给脚本执行权限:
chmod +x /usr/local/bin/disk-auto-clean.sh - 手动测试:
/usr/local/bin/disk-auto-clean.sh --force - 加定时任务:每10分钟执行一次同一个脚本
这是一篇给新手小白的完整实战教程。目标是:当磁盘占用超过阈值时自动清理,并推送Telegram通知;同时支持系统自动识别(Debian/Ubuntu/CentOS)、清理失败告警、每日汇总报告。
📌 你将得到什么
- 自动识别系统并执行对应清理命令
- 磁盘占用超过阈值(默认88%)自动清理
- 清理成功/失败都会推送Telegram
- 每天固定时间推送“日报”
- 通知使用中文,且不显示公网IP/主机名
🧰 准备工作
- 你是
root用户(或命令前加sudo) - 系统时间正确:执行
date看时间是否正常 - 服务器能上外网:执行
curl -I https://api.telegram.org - Telegram 机器人已经被拉进你的频道
- 一台Linux服务器(Debian/Ubuntu/CentOS/Rocky/AlmaLinux均可)
- root权限
- Telegram Bot Token
- Telegram频道Chat ID(通常是
-100xxxxxxxxxx) - 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,不是改脚本文件名。
- 执行
crontab -e打开定时任务编辑器(文件一般所在位置/bin/nano) - 把下面两行粘贴进去(有重复就保留一份)
- 保存并退出(生效)
- 执行
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能收到消息”。
- 命令执行后没有报错(返回命令行)
- Telegram频道收到“磁盘自动清理通知”或“每日汇总”
- 可选检查:
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
