本文目录导读:

可以使用多种脚本语言来检测磁盘健康状况,以下提供Bash、Python、PowerShell三种主流方案,涵盖SMART检测、坏道扫描、IO性能测试等维度。
Bash脚本(Linux/macOS环境)
适用于快速检测物理/逻辑磁盘的健康状态,结合smartctl和df命令。
基础健康检测脚本(SMART + 空间)
#!/bin/bash
# 文件名: disk_health_check.sh
# 功能: 检测磁盘SMART状态和分区使用率
echo "==========磁盘SMART健康状态=========="
echo "检测时间: $(date '+%Y-%m-%d %H:%M:%S')"
# 检测所有物理磁盘(支持NVMe和SATA)
for disk in $(lsblk -dp | grep -oP '^/dev/\K\w+'); do
if [ -e "/dev/$disk" ]; then
echo "-----------------------------------"
echo "磁盘: /dev/$disk"
# 检查是否有smartctl工具
if command -v smartctl >/dev/null 2>&1; then
# 输出健康状态(关键信息)
smartctl -H /dev/$disk | grep -E "SMART health|SMART overall-health"
# 检查是否支持SMART
if smartctl -i /dev/$disk | grep -q "SMART support is: Enabled"; then
echo "SMART状态: 已启用"
# 检查关键错误计数
smartctl -a /dev/$disk | grep -E "Reallocated_Sector_Ct|Current_Pending_Sector|Offline_Uncorrectable"
else
echo "SMART状态: 不支持或未启用"
fi
else
echo "警告: 未安装smartmontools(请执行 sudo apt install smartmontools)"
fi
fi
done
echo ""
echo "==========分区使用率=========="
df -h | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{print $1, "\t已用:", $3, "\t可用:", $4, "\t使用率:", $5}'
高级扩展脚本(含坏道和IO性能)
#!/bin/bash
# 扩展功能: 坏道检查+写入性能测试
echo "==========坏道检测(只读测试)=========="
read -p "请输入要检测的磁盘(如: sda): " disk_name
if [ -e "/dev/$disk_name" ]; then
# 使用badblocks只读模式检测(不破坏数据)
echo "开始检测坏道,大约需要几分钟..."
sudo badblocks -sv /dev/$disk_name | tail -5
else
echo "磁盘不存在"
fi
echo ""
echo "==========写入性能测试(30秒)=========="
# 使用dd测试写入速度
dd if=/dev/zero of=/tmp/testfile bs=1M count=1024 conv=fdatasync 2>&1 | tail -1
rm -f /tmp/testfile
Python 3脚本(跨平台)
适合需要数据结构化输出的场景,可生成JSON报告。
#!/usr/bin/env python3
# 文件名: disk_analyzer.py
import subprocess
import json
import platform
import re
from datetime import datetime
def get_smart_data(disk):
"""Linux/macOS下获取SMART数据"""
try:
# 先检查是否支持SMART
check_cmd = f"smartctl -i /dev/{disk}"
if "SMART support is: Enabled" not in subprocess.getoutput(check_cmd):
return {"status": "unsupported"}
output = subprocess.getoutput(f"smartctl -a /dev/{disk}")
data = {
"health": "unknown",
"reallocated_sectors": None,
"pending_sectors": None
}
# 解析关键指标
if "SMART overall-health self-assessment test result: PASSED" in output:
data["health"] = "PASSED"
elif "FAILED" in output:
data["health"] = "FAILED"
# 解析SMART属性
patterns = {
"reallocated_sectors": r"Reallocated_Sector_Ct\s+\S+\s+\S+\s+(\d+)",
"pending_sectors": r"Current_Pending_Sector\s+\S+\s+\S+\s+(\d+)"
}
for key, pattern in patterns.items():
match = re.search(pattern, output)
if match:
data[key] = int(match.group(1))
return data
except Exception as e:
return {"error": str(e)}
def get_windows_disk_health():
"""Windows下使用PowerShell获取磁盘健康信息(针对于Windows逻辑驱动器)"""
ps_script = """
Get-PhysicalDisk | Select-Object DeviceId, FriendlyName, HealthStatus, OperationalStatus | ConvertTo-Json
"""
result = subprocess.run(["powershell", "-Command", ps_script], capture_output=True, text=True)
if result.returncode == 0:
return json.loads(result.stdout)
return {"error": "PowerShell查询失败"}
def main():
system = platform.system()
report = {
"timestamp": datetime.now().isoformat(),
"platform": system
}
disks_info = []
if system == "Linux":
# 获取所有物理磁盘
lsblk_output = subprocess.getoutput("lsblk -d -o NAME -n")
disks = [d for d in lsblk_output.split("\n") if d]
for disk in disks:
info = {"disk": f"/dev/{disk}"}
info.update(get_smart_data(disk))
# 获取分区使用率
df_info = subprocess.getoutput(f"df -h /dev/{disk}* 2>/dev/null | tail -n +2")
if df_info:
info["partitions"] = df_info.split("\n")
disks_info.append(info)
elif system == "Windows":
disks_info = get_windows_disk_health()
else: # macOS
# macOS有些版本不支持smartctl,如果安装了就使用
disks = subprocess.getoutput("diskutil list | grep -E '^/dev/disk' | awk '{print $1}'").split("\n")
for disk in disks:
info = {"disk": disk}
smart_output = subprocess.getoutput(f"diskutil info {disk} | grep -E 'SMART|Health'")
info["smart_info"] = smart_output
disks_info.append(info)
report["disks"] = disks_info
# 输出JSON报告
print(json.dumps(report, indent=2, ensure_ascii=False))
# 直观的健康度判断
print("\n===健康度快速评估===")
for disk in disks_info:
if "health" in disk and disk["health"] == "PASSED":
print(f"{disk['disk']}: ✅ 健康")
elif "reallocated_sectors" in disk and disk["reallocated_sectors"] and disk["reallocated_sectors"] > 0:
print(f"{disk['disk']}: ⚠️ 存在重映射扇区({disk['reallocated_sectors']}),建议备份数据")
elif "HealthStatus" in disk:
status = disk.get("HealthStatus", "未知")
print(f"磁盘 {disk.get('DeviceId','?')}: {'✅' if status=='Healthy' else '⚠️'} {status}")
else:
print(f"磁盘状态未知,请手动检查")
if __name__ == "__main__":
if platform.system() != "Windows":
# Linux/macOS需要root权限读取SMART
if subprocess.geteuid() != 0:
print("警告: 部分功能需要root权限,建议使用 sudo 运行")
main()
PowerShell脚本(Windows专用)
针对Windows环境,利用系统自带的Get-PhysicalDisk(电源管理)和WMI。
# 文件名: check_disk_health.ps1
Write-Host "========== Windows 磁盘健康检测 ==========" -ForegroundColor Cyan
# 第一部分:使用物理磁盘API(Windows 8+)
Write-Host "`n[1] 物理磁盘基础状态" -ForegroundColor Yellow
try {
Get-PhysicalDisk | Format-Table DeviceId, FriendlyName, MediaType, HealthStatus, OperationalStatus -AutoSize
} catch {
Write-Warning "无法获取物理磁盘信息: $_"
}
# 第二部分:逻辑磁盘健康状态(兼容旧系统)
Write-Host "`n[2] 逻辑卷健康状态" -ForegroundColor Yellow
Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" |
ForEach-Object {
[PSCustomObject]@{
盘符 = $_.DeviceID
卷标 = $_.VolumeName
大小_GB = [math]::Round($_.Size/1GB, 2)
已用_GB = [math]::Round(($_.Size - $_.FreeSpace)/1GB, 2)
可用_GB = [math]::Round($_.FreeSpace/1GB, 2)
使用率 = "{0:P2}" -f (($_.Size - $_.FreeSpace) / $_.Size)
}
} | Format-Table -AutoSize
# 第三部分:SMART事件记录
Write-Host "`n[3] 磁盘致命错误事件(最近7天)" -ForegroundColor Yellow
Get-WinEvent -FilterHashtable @{LogName='System'; Level=2; StartTime=(Get-Date).AddDays(-7)} -ErrorAction SilentlyContinue |
Where-Object { $_.Message -match 'disk|SCSI|hard drive' } |
Select-Object TimeCreated, ProviderName, Message |
Format-Table -AutoSize
# 第四部分:如果存在MegaCLI/StorCLI则检测RAID状态
Write-Host "`n[4] RAID控制器状态(如适用)" -ForegroundColor Yellow
if (Get-Command storcli -ErrorAction SilentlyContinue) {
storcli /c0 show | Select-String "Status|State"
} elseif (Get-Command megacli -ErrorAction SilentlyContinue) {
megacli -LDInfo -Lall -aALL | Select-String "State"
} else {
Write-Host "未检测到StorCLI/MegaCLI工具,跳过RAID检查" -ForegroundColor Gray
}
自动化定时检查(Linux示例)
推荐配置Cron实现每日自动检查并发送告警:
# 创建定时任务(每天6点执行) (crontab -l 2>/dev/null; echo "0 6 * * * /bin/bash /root/disk_check.sh | mail -s '服务器磁盘状态' admin@example.com") | crontab - # 或者使用systemd定时器 cat > /etc/systemd/system/disk-check.service << EOF [Unit] Description=磁盘健康检查 [Service] Type=oneshot ExecStart=/bin/bash /root/disk_check.sh -v [Install] WantedBy=multi-user.target EOF cat > /etc/systemd/system/disk-check.timer << EOF [Unit] Description=每日磁盘检查定时器 [Timer] OnCalendar=*-*-* 06:00:00 Persistent=true [Install] WantedBy=timers.target EOF systemctl enable --now disk-check.timer
关键检测指标解读
| 指标 | 建议阈值 | 严重级别 |
|---|---|---|
| 重分配扇区(Reallocated) | >100 | 🔴高危 - 立即换盘 |
| 待重映射扇区(Pending) | >20 | 🟡警告 - 持续观察 |
| SMART通过状态 | FAILED | 🔴危险 - 系统已判定故障 |
| 磁盘温度 | >55°C | 🟠偏高 - 可能散热问题 |
| 坏道数量 | >5个 | 🔴严重 - 数据安全威胁 |
使用建议:日常只需运行Bash脚本,如需图形化界面可使用gsmartcontrol(Linux)或CrystalDiskInfo(Windows)GUI工具,生产环境建议将脚本接入监控系统(如Prometheus + node_exporter的smartmon插件)。