本文目录导读:

在脚本中进行磁盘空间检查并实现预警,通常涉及以下几个关键步骤:获取磁盘使用率、设置阈值、执行预警动作(如写入日志、发送邮件、或系统通知)。
以下是几种常见脚本语言(Shell、Python、PowerShell)的实现方法,以及如何让预警机制更可靠。
核心预警逻辑(跨语言通用)
获取根目录 (/) 或指定挂载点的使用率百分比。 2. 比较使用率与预设的阈值(80% -> 警告, 90% -> 严重)。 3. 如果超出阈值,则执行预警动作。 4. 建议加入 `$?` 或异常捕获,防止脚本自己因磁盘满而执行失败。
具体实现示例
A. Bash/Shell 脚本 (Linux/macOS)
这是服务器运维中最常用的方式,核心是解析 df 命令的输出。
#!/bin/bash
# --- 配置区 ---
WARN_THRESHOLD=80 # 警告阈值 (%)
CRIT_THRESHOLD=90 # 严重阈值 (%)
MOUNT_POINT="/" # 监控的挂载点(根目录)
LOG_FILE="/var/log/disk_check.log"
# --- 核心逻辑 ---
# 使用 df 获取使用率,去掉表头,提取第5列(使用率%),去掉 % 符号
USAGE=$(df -h "$MOUNT_POINT" | awk 'NR==2 {print $5}' | sed 's/%//')
# 检查是否成功获取数值(防止 df 命令失败)
if ! [[ "$USAGE" =~ ^[0-9]+$ ]]; then
echo "$(date) [ERROR] 无法获取磁盘使用率,df命令可能失败。" >> "$LOG_FILE"
exit 1
fi
# --- 预警判断 ---
if [ "$USAGE" -ge "$CRIT_THRESHOLD" ]; then
echo "$(date) [CRITICAL] 磁盘使用率已达 ${USAGE}%,超过严重阈值 ${CRIT_THRESHOLD}%。" | tee -a "$LOG_FILE"
# 在此处执行严重动作:发邮件、调API、重启服务等
# mail -s "CRITICAL: Disk Full" admin@example.com < "$LOG_FILE"
# curl -s -X POST http://alerting.example.com/alert -d "status=critical"
elif [ "$USAGE" -ge "$WARN_THRESHOLD" ]; then
echo "$(date) [WARNING] 磁盘使用率为 ${USAGE}%,超过警告阈值 ${WARN_THRESHOLD}%。" >> "$LOG_FILE"
# 在此处执行警告动作:写日志、发企业微信/钉钉通知等
fi
预警效果:
- 磁盘占用超过80%:日志记录
[WARNING] - 磁盘占用超过90%:日志记录
[CRITICAL]并tee到终端和日志文件
B. Python 脚本 (跨平台)
Python 更灵活,适合复杂的告警逻辑(如多分区监控、历史趋势分析)。
import shutil
import os
import logging
import smtplib
from datetime import datetime
# --- 配置区 ---
WARN_THRESHOLD = 80
CRIT_THRESHOLD = 90
TOTAL_GB_WARN = 50 # 可选:剩余空间低于50G即预警
MOUNT_POINT = "/" # Windows 下为 "C:\\"
# 配置日志
logging.basicConfig(filename='/var/log/disk_check.log', level=logging.INFO,
format='%(asctime)s %(levelname)s %(message)s')
def check_disk_usage(path):
"""获取磁盘使用率 (0-100) 和剩余空间 (GB)"""
usage = shutil.disk_usage(path)
percent = (usage.used / usage.total) * 100
free_gb = usage.free / (2**30) # 转换为GB
return percent, free_gb
def send_alert(msg, level):
"""发送预警通知 (示例: 写入日志 + 打印)"""
if level == 'CRITICAL':
logging.critical(msg)
print(f"[{level}] {msg}")
# 可在此处添加真实发送代码 (邮件/短信/API)
else:
logging.warning(msg)
print(f"[{level}] {msg}")
# --- 主逻辑 ---
try:
percent, free_gb = check_disk_usage(MOUNT_POINT)
if percent >= CRIT_THRESHOLD or free_gb < TOTAL_GB_WARN:
send_alert(f"磁盘使用率 {percent:.1f}%,剩余空间 {free_gb:.1f}GB,已达严重阈值!", 'CRITICAL')
elif percent >= WARN_THRESHOLD:
send_alert(f"磁盘使用率 {percent:.1f}%,剩余空间 {free_gb:.1f}GB,已达警告阈值.", 'WARNING')
else:
logging.info(f"正常: 使用率 {percent:.1f}%,剩余 {free_gb:.1f}GB")
except Exception as e:
logging.error(f"检查磁盘时出错: {e}")
Python 优势:可以轻松结合 psutil 库进行更高级的监控。
C. PowerShell 脚本 (Windows)
Windows 环境下推荐使用 WMI 或 Get-PSDrive。
# --- 配置区 ---
$WarnThreshold = 80
$CritThreshold = 90
$Drive = "C" # 驱动器盘符
$LogFile = "C:\Logs\disk_check.log"
# --- 获取磁盘使用率 ---
$DriveInfo = Get-PSDrive -Name $Drive -PSProvider FileSystem
$UsedPercent = [math]::Round(($DriveInfo.Used / $DriveInfo.Used + $DriveInfo.Free) * 100, 1)
# --- 预警判断 ---
if ($UsedPercent -ge $CritThreshold) {
$Message = "[CRITICAL] $Drive 盘使用率已达 $UsedPercent%,超过严重阈值 $CritThreshold%。"
Write-Host $Message -ForegroundColor Red
Add-Content -Path $LogFile -Value "$(Get-Date) $Message"
# 在此处执行严重动作
# Send-MailMessage -To "admin@example.com" ...
} elseif ($UsedPercent -ge $WarnThreshold) {
$Message = "[WARNING] $Drive 盘使用率为 $UsedPercent%,超过警告阈值 $WarnThreshold%。"
Write-Host $Message -ForegroundColor Yellow
Add-Content -Path $LogFile -Value "$(Get-Date) $Message"
}
关键预警机制设计(避免“狼来了”)
-
分级预警:不要只设一个阈值。
- 80%:警告(记录日志,日常巡检)
- 90%:严重(立即发邮件/短信,通知值班人员)
- 95%:紧急(尝试自动清理临时文件)
-
去重与防抖动:如果磁盘在阈值边缘波动(如89%-91%),不要每5分钟发一次警告。
- 使用状态文件记录上次预警等级。
- 只有当状态从
正常→警告或从警告→严重时才发送通知。 - 避免在
严重状态下反复发送相同级别的邮件。
-
基于剩余空间而非仅百分比:
- 对于大容量磁盘(如10TB),10%剩余还有1TB,无需预警;但对于小磁盘(如40GB),10%只剩4GB就很危险。
- 推荐:同时检查 使用率 和 绝对剩余空间(如剩余<10GB则触发严重预警)。
-
异常处理:
- 当磁盘100%满时,
df或shutil可能返回异常数据或超时,脚本应能捕获错误并输出“检查失败,可能磁盘已满或IO错误”的日志。
- 当磁盘100%满时,
-
循环监控(配合计划任务):
- Linux:放入 crontab,每5-15分钟执行一次。
- Windows:使用任务计划程序。
- 不要在脚本内
while true; sleep 60死循环,除非是守护进程。
实战建议:一个高可靠性的预警脚本框架
# 在脚本中加入这个函数,用于检测磁盘100%满时的自我保护
safe_df() {
# 如果磁盘已满,df -h 可能卡住,使用 timeout 命令限制执行时间
timeout 5 df -h "$1" 2>/dev/null || echo "0%"
}
# 然后解析 safe_df 的输出
USAGE=$(safe_df "/" | awk 'NR==2 {print $5}' | sed 's/%//')
- 最简方案:Bash +
df+ crontab。 - 最强可控性:Python +
shutil+ 状态文件去重。 - 关键点:分级阈值、防重复通知、剩余空间与百分比双重判断、保护脚本自身不因磁盘满而崩溃。