如何用脚本检查磁盘错误

wen 实用脚本 1

磁盘健康哨兵:用自动化脚本精准排查与修复硬盘错误(附Bash/PowerShell实战代码)


目录导读(Table of Contents)

  1. 为什么你的磁盘需要“体检”? —— 认识坏道、逻辑错误与文件系统损伤的早期信号
  2. 脚本检查的“黄金组合” —— 原生工具(CHKDSK/fsck) vs. 自动化脚本的优劣对比
  3. Bash脚本实战:Linux/macOS下的fsck深度巡检
    • 1 自动卸载挂载点并执行只读检查
    • 2 将错误日志注入系统报告并触发邮件告警
  4. PowerShell脚本实战:Windows下的chkdsk静默扫描与计划任务绑定
    • 1 非交互式扫描并导出CSV健康报告
    • 2 结合事件日志实现故障自愈重启
  5. 高级技巧:用smartctl+inotify构建实时坏道监控
  6. FAQ 问答专区:你关心的5个磁盘脚本问题
  7. 从“救火队员”到“预警雷达”的转型

为什么你的磁盘需要“体检”?

当服务器响应缓慢、文件突然损坏或系统频繁蓝屏时,90%的根因都指向磁盘逻辑错误或物理坏道,Windows的chkdsk和Linux的fsck虽然功能强大,但作为命令行工具,它们需要人工判断参数和时机。脚本的价值在于:将“诊断-修复-报告”流程标准化,并实现无人值守的定时巡检,一个简单的Bash循环可以每周末凌晨自动检查/dev/sdb,而无需管理员熬夜盯着终端。

如何用脚本检查磁盘错误

脚本检查的“黄金组合”

工具 适用系统 检查级别 脚本化难点
chkdsk /f Windows 文件系统逻辑错误 需计划任务+输出重定向
fsck -y Linux 文件系统完整性 需处理挂载状态
smartctl -t long 跨平台 物理磁盘SMART检测 需解析长输出文本

脚本的核心策略:优先执行非破坏性只读检查(如fsck -n),将关键错误码(如exit code 4代表未修复错误)捕获后,再决定是否进入-y自动修复模式。

Bash脚本实战:Linux/macOS下的fsck深度巡检

#!/bin/bash
# 文件名: disk_health_guard.sh
# 需以root身份运行,通过crontab绑定每周日02:00执行
MOUNT_POINT="/data"
DEVICE="/dev/sdb1"
LOG_FILE="/var/log/disk_check_$(date +%Y%m%d).log"
# 步骤1:安全卸载目标分区(若已挂载)
umount $MOUNT_POINT 2>/dev/null || true
# 步骤2:执行非交互只读检查,捕获退出码
fsck -n $DEVICE &> $LOG_FILE
EXIT_CODE=$?
# 步骤3:根据退出码策略处理
if [ $EXIT_CODE -eq 0 ]; then
    echo "✓ 磁盘无错误" >> $LOG_FILE
elif [ $EXIT_CODE -eq 1 ]; then
    echo "⚠ 发现可修复错误,执行自动修复(需重新挂载为读写)" >> $LOG_FILE
    mount -o remount,rw $MOUNT_POINT
    fsck -y $DEVICE >> $LOG_FILE 2>&1
elif [ $EXIT_CODE -ge 4 ]; then
    echo "✗ 存在未修复错误,需人工介入(返回码$EXIT_CODE)" >> $LOG_FILE
    # 可选:通过mailx发送告警邮件
    mail -s "磁盘严重错误警告" admin@example.com < $LOG_FILE
fi
# 步骤4:无论结果如何,重新挂载分区
mount $MOUNT_POINT

为何这样写:使用-n参数避免交互输入,同时保留文件系统的原始状态;利用退出码分级处理,既保证自动化又不盲目使用-y导致数据丢失。

PowerShell脚本实战:Windows下的chkdsk静默扫描与计划任务绑定

# 文件名: disk_check.ps1
# 配合任务计划程序,设置“无论用户是否登录都要运行”,并用最高权限执行
$drive = "D:"
$outputFile = "C:\temp\chkdsk_$((Get-Date).ToString('yyyyMMdd')).csv"
# 使用 /scan 参数(Windows 10 1803+),非重启即可完成在线扫描
$result = chkdsk $drive /scan
# 解析输出中的关键行,构建结构化报告
$summary = $result | Select-String -Pattern "文件系统状态|问题|可用空间" | ForEach-Object {
    $_.Line.Trim()
}
# 导出CSV格式报告
$summary | Out-File $outputFile -Encoding UTF8
# 若包含“发现错误”字样,则触发修复计划(需重启计划)
if ($result -match "发现错误" -or $result -match "has problems") {
    Write-Host "检测到错误,安排重启后修复(chkdsk /spotfix)" -BackgroundColor Yellow
    chkdsk $drive /spotfix  # /spotfix 可在线修复关键元数据,无需重启
} else {
    Write-Host "磁盘D:健康状态良好。"
}

进阶提示:结合Get-WinEvent -FilterHashtable @{LogName='System'; Id=26226}实时监听磁盘错误事件,当事件出现时自动触发此脚本。

高级技巧:用smartctl+inotify构建实时坏道监控

smartctl能读取SMART属性(如Reallocated_Sector_Ct),当数值超过阈值时,脚本会用inotifywait监控内核日志并即时启动fsck,以下为关键片段:

# 当SMART属性“当前待映射扇区”>10时,自动启动深度扫描
if [ $(smartctl -A /dev/sda | awk '/Current_Pending_Sector/{print $10}') -gt 10 ]; then
   echo "$(date): 物理坏道风险激增,立即执行离线扫描" | systemd-cat
   echo 1 > /proc/sys/vm/drop_caches
   fsck -y /dev/sda2 &
fi

此方法将传统被动排查转向基于硬件预警的实时干预

FAQ 问答专区:你关心的5个磁盘脚本问题

Q1:脚本运行时磁盘被占用,无法卸载怎么办? A:先执行lsof +D /路径找到占用进程,使用fuser -km /路径强制结束;若仍失败,需在启动加载前(如Linux的initramfs阶段)运行脚本。

Q2:如何避免fsck -y误删数据? A:务必先运行-n只读检查,并将输出保存,确认错误属于“可清除的纯日志型”(如孤儿文件),再手动执行-y;生产环境建议在维护窗口操作。

Q3:Windows下如何实现定期自动检查? A:使用任务计划程序注册PowerShell脚本,触发器设置为“启动时”或“每周某天”,并选择“使用最高权限运行”和“隐藏窗口”选项。

Q4:脚本如何识别不同文件系统(NTFS/EXT4/XFS)? A:通过blkid(Linux)或Get-Volume(Windows)获取文件系统类型,然后动态选择fsck.ext4chkdsk /f命令。[ $(blkid -s TYPE -o value $DEV) = "ext4" ] && fsck.ext4 -n $DEV

Q5:检查结果如何集成到监控面板(如Zabbix)? A:脚本将状态码与检查时间输出为JSON格式({"status":"error","codes":4}),通过curl推送到Zabbix Trapper接口,或直接写入/var/loglogstash收集。

从“救火队员”到“预警雷达”的转型

检查磁盘错误不应等到用户投诉才启动,通过上述脚本,你已将任务从“手动运行命令”升级为“自动化探测-分级响应-证据留存”,记住三个核心原则:

  • 优先只读:所有自动化流程第一步必须是-n/scan,避免不必要的写操作。
  • 状态码即信号:将fsck的51个退出码和chkdsk的%errorlevel%映射到具体的告警级别。
  • 日志即文档:每次检查生成的带时间戳日志,是故障复盘和性能调优的珍贵资产。

带上你的脚本,让每一块磁盘都在你的掌控之下,当坏道初见端倪时,脚本已经默默为你排除了下一次数据灾难。

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