如何写一个脚本检测磁盘坏道

wen 实用脚本 1

从入门到精通的完整指南

目录导读

  1. 为什么要用脚本检测磁盘坏道?
  2. 磁盘坏道检测的基本原理
  3. 准备工作:你需要了解的系统和工具
  4. 实战脚本编写——Linux下基于badblocks的自动化检测
  5. 实战脚本编写——Windows下基于WMIC与第三方工具的检测
  6. 脚本进阶:自动报警、日志与定期任务
  7. 常见问题与问答(FAQ)
  8. 总结与最佳实践

为什么要用脚本检测磁盘坏道?

磁盘坏道(Bad Sector)是硬盘物理或逻辑损伤导致的存储区域无法正常读写,传统手动检测依赖图形化工具(如HD Tune、CrystalDiskInfo),但无法批量、定时、自动化,脚本检测的优势在于:

如何写一个脚本检测磁盘坏道

  • 批量管理:同时检测多块磁盘(服务器、NAS、存储阵列)。
  • 定时调度:设置cron任务或计划任务,定期检查。
  • 告警集成:发现坏道时自动发送邮件、短信或写入日志。
  • 成本节约:免费开源,避免付费软件的订阅费用。

核心问题:脚本能检测出所有类型的坏道吗?
答案:脚本可检测物理坏道(不可修复)和逻辑坏道(可通过写入零或低级格式化修复),但无法检测控制器故障或电缆松动的间歇性错误,需配合S.M.A.R.T.数据。


磁盘坏道检测的基本原理

  • 读取验证:向磁盘写入特定数据模式(如0x00、0xFF),再读取并与原数据比对,若读取失败或数据不匹配,则该扇区标记为坏道。
  • S.M.A.R.T.属性:硬盘自带的自我监控技术,脚本可读取Reallocated_Sector_Ct(重映射扇区数)、Current_Pending_Sector(待重映射扇区)等关键参数。
  • 坏块表:文件系统(如EXT4、NTFS)会维护坏块表(bad blocks list),脚本可扫描文件系统并更新该表。

不同检测方式的误报率

  • 快速读取测试(如badblocks -sv):几分钟完成,但可能漏检。
  • 破坏性写入测试(badblocks -w):彻底但需数小时,且会清除数据。
  • S.M.A.R.T.日志分析:非侵入式,但仅反映历史数据。

问答:
Q:脚本会不会破坏磁盘数据?
A: 取决于模式,写入测试(-w)会覆盖所有扇区,必须确保磁盘无重要数据,安全做法是使用非破坏性读取测试(-n或-s)或只读取S.M.A.R.T.日志。


准备工作:你需要了解的系统和工具

1 Linux环境

  • badblocks:Linux原生工具,支持破坏性/非破坏性检测。
  • smartctl:读取S.M.A.R.T.数据,来自smartmontools包。
  • dd:用于低层级读写操作,配合坏道隔离。
  • 脚本语言:Bash首选,也可用Python(更灵活,支持多线程)。

2 Windows环境

  • WMIC:内置命令行工具,可查询S.M.A.R.T.属性(需管理员权限)。
  • ChkDsk:系统磁盘检查工具,但仅支持完整磁盘扫描。
  • 第三方CLI工具:如Victoria(命令行版)、HDDScan(支持脚本调用)。注意:本文案例使用wmicfsutil,避免依赖不稳定的第三方工具。
  • PowerShell:推荐,可调用.NET类直接读取磁盘健康状态。

3 通用注意事项

  • 磁盘识别:Linux用/dev/sda,Windows用\\.\PhysicalDrive0C:
  • 权限要求:Linux需要root权限读取原始设备;Windows需要管理员权限。
  • 备份数据:任何低级写入操作前必须备份。

实战脚本编写——Linux下基于badblocks的自动化检测

1 基础非破坏性检测脚本

#!/bin/bash
# 脚本名:disk_bad_sector_checker.sh
# 用途:扫描指定磁盘,输出坏道位置和数量
DISK="/dev/sda"
LOG_FILE="/var/log/bad_sector_scan.log"
echo "开始扫描 $DISK,时间:$(date)" >> $LOG_FILE
badblocks -sv $DISK 2>&1 | tee -a $LOG_FILE
echo "扫描结束,时间:$(date)" >> $LOG_FILE

参数说明

  • -s 显示进度条
  • -v 详细输出(显示每个坏道偏移量)
  • 默认检测模式为读取测试(不写入数据)

2 带S.M.A.R.T.数据联动的脚本

#!/bin/bash
DISK="/dev/sda"
THRESHOLD=10  # 重映射扇区阈值
# 获取重映射扇区数
REALLOC=$(smartctl -A $DISK | grep "Reallocated_Sector_Ct" | awk '{print $10}')
if [ "$REALLOC" -gt "$THRESHOLD" ]; then
    echo "警告:$DISK 重映射扇区数 ($REALLOC) 超过阈值 ($THRESHOLD)"
    # 触发全盘坏道扫描
    badblocks -sv $DISK > /tmp/bad_block_list.txt
else
    echo "正常:重映射扇区数 $REALLOC"
fi

3 定期调度(cron)

# 添加到crontab,每周日凌晨2点执行
0 2 * * 0 /usr/local/bin/disk_bad_sector_checker.sh

问答:
Q:如果磁盘在扫描过程中挂载,会发生什么?
A: badblocks对挂载的磁盘进行读取测试是安全的(-s-n模式),但写入测试(-w)必须卸载,否则会导致文件系统损坏。


实战脚本编写——Windows下基于WMIC与第三方工具的检测

1 使用PowerShell读取S.M.A.R.T.属性

# 脚本名:SMART_Check.ps1
# 功能:检测所有物理磁盘的重映射扇区数
$threshold = 10
$disks = Get-WmiObject -Namespace "root\wmi" -Query "SELECT * FROM MSStorageDriver_FailurePredictStatus"
foreach ($disk in $disks) {
    $predict = $disk.FailurePredictThreshold
    if ($predict -gt 0) {
        Write-Host "磁盘 $($disk.InstanceName) 存在坏道风险"
    }
}

注意:WMIC的S.M.A.R.T.支持依赖于硬盘和驱动,部分SSD可能不兼容。

2 使用fsutil与chkdsk组合(适合检测系统盘)

@echo off
REM 脚本名:disk_check.bat
REM 注意:chkdsk对系统盘(C:)只能计划到下次重启
echo 正在运行非破坏性磁盘检查...
fsutil dirty query C:
chkdsk C: /scan 2>&1

3 高级PowerShell脚本:集成报警与日志

$computer = $env:COMPUTERNAME
$disk = "\\.\PhysicalDrive0"
$logPath = "C:\Logs\BadSector_$computer.csv"
# 调用第三方工具(需预先安装并配入PATH)
$result = & "badblocks.exe" -sv $disk
# 解析输出并写入CSV
$badSectors = $result | Select-String "坏块" 
if ($badSectors.Count -gt 0) {
    $row = [PSCustomObject]@{
        Time = Get-Date -Format "yyyy-MM-dd HH:mm"
        Disk = $disk
        BadCount = $badSectors.Count
    }
    $row | Export-Csv -Path $logPath -Append -NoTypeInformation
    # 发送邮件(需配置SMTP)
    # Send-MailMessage -To "admin@example.com" -Subject "坏道告警" -Body "检测到$badSectors.Count个坏道"
}

注意badblocks.exe是Linux工具移植版(如Cygwin),Windows原生没有类似工具,若没有,可用Victoria命令行版或HDDScan的命令行输出。


脚本进阶:自动报警、日志与定期任务

1 日志轮转与管理

# Linux下,使用logrotate管理日志
# 配置 /etc/logrotate.d/diskcheck
/var/log/bad_sector_scan.log {
    daily
    rotate 30
    compress
    missingok
    notifempty
}

2 多磁盘并行检测

# Python脚本示例(跨平台)
import subprocess
import threading
disks = ["/dev/sda", "/dev/sdb"]
def check_disk(disk):
    result = subprocess.run(["badblocks", "-sv", disk], capture_output=True, text=True)
    print(f"磁盘 {disk} 检测完成")
threads = [threading.Thread(target=check_disk, args=(d,)) for d in disks]
for t in threads:
    t.start()
for t in threads:
    t.join()

3 与告警系统集成

  • 邮件告警:Linux用mailutilsmsmtp;Windows用Send-MailMessage
  • 企业级集成:通过脚本写入日志,再被Prometheus/Grafana监控;或直接推送至Slack/钉钉Webhook。

常见问题与问答(FAQ)

Q1:脚本检测出坏道后,该如何处理?

A: 如果数量少(<10个),可使用badblocks -w尝试修复逻辑坏道,物理坏道则需隔离:记录偏移地址,用dd跳过该区域,或直接更换硬盘。重要提示:任何修复前必须备份数据。

Q2:为什么用脚本检测不到坏道,但系统已经卡顿?

A: 可能原因:①坏道集中在系统元数据区域,导致文件系统挂起(而脚本只扫描数据区域);②是控制器故障而非磁盘坏道;③是SSD的磨损均衡导致的延迟,而非坏道,建议结合S.M.A.R.T.的Current_Pending_SectorOffline_Uncorrectable属性综合判断。

Q3:脚本能否检测SSD的坏道?

A: 传统坏道概念适用于机械硬盘(HDD),SSD使用NAND闪存,坏块由主控管理,用户层难以直接检测,但可通过S.M.A.R.T.的Media_Wearout_Indicator(磨损指标)和Reallocated_Sector_Ct(重映射块数)评估健康度。

Q4:如何确保脚本长时间运行不中断?

A: 在Linux下使用nohupscreen工具;Windows下使用PowerShell的后台任务Start-Job,如果是服务器,建议在非高峰时段运行,并设置超时保护。

Q5:脚本检测后如何生成报告?

A: 推荐输出为CSV或JSON格式。

badblocks -sv /dev/sda | grep -oP "坏块 \K[0-9]+" > bad_sectors_$(date +%Y%m%d).txt

总结与最佳实践

1 脚本检测 vs 图形化工具

方面 脚本 图形化工具
自动化 完全可控 依赖手动操作
批量 支持多磁盘 逐个点击
报告粒度 可定制 固定格式
用户友好 需学习 直观易用

2 推荐实施流程

  1. 初始扫描:首次使用脚本对所有磁盘进行全盘检测,并记录S.M.A.R.T.基线。
  2. 定期检查:每周运行一次快速非破坏性扫描(约每TB 1小时),每月一次完整扫描。
  3. 阈值管理:当重映射扇区数 > 10 或连续坏道数 > 20 时,自动替换磁盘。
  4. 日志分析:使用类似ELKSplunk的工具分析历史趋势。

3 最后的提醒

  • 不要在生产环境磁盘上使用破坏性写入测试。
  • 脚本检测无法100%替代专业工具,对关键业务建议配合硬件RAID监控。
  • 对于大规模存储集群,推荐使用smartd(Linux自带S.M.A.R.T.守护进程)作为第一道防线,脚本作为深层检测。

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