如何用脚本检测磁盘健康

wen 实用脚本 2

本文目录导读:

如何用脚本检测磁盘健康

  1. 方案一:Bash脚本(Linux/macOS环境)
  2. 方案二:Python 3脚本(跨平台)
  3. 方案三:PowerShell脚本(Windows专用)
  4. 自动化定时检查(Linux示例)
  5. 关键检测指标解读

可以使用多种脚本语言来检测磁盘健康状况,以下提供Bash、Python、PowerShell三种主流方案,涵盖SMART检测、坏道扫描、IO性能测试等维度。


Bash脚本(Linux/macOS环境)

适用于快速检测物理/逻辑磁盘的健康状态,结合smartctldf命令。

基础健康检测脚本(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插件)。

抱歉,评论功能暂时关闭!