停止在 Linux 上猜测磁盘健康:使用 SMART + NVMe 检查和 systemd 定时器警报

发布: (2026年3月7日 GMT+8 13:01)
3 分钟阅读
原文: Dev.to

Source: Dev.to

概览

即使你的备份完美、服务已经加固,但如果存储健康状况悄然恶化,仍然可能失去整个周末(甚至数据)。
本指南提供了一套实用、可审计的 Linux 磁盘健康工作流:

  • 扫描 ATA/SATA/SAS/NVMe 设备
  • 使用 smartctl 进行健康检查
  • 使用 nvme smart‑log 拉取 NVMe 遥测数据
  • 当出现异常时在 systemd/journald 中发出强烈警报
  • 使用持久定时器安排检查

无需仪表盘——只要可靠的信号即可。

安装

# Debian/Ubuntu
sudo apt update
sudo apt install -y smartmontools nvme-cli jq

# Fedora/CentOS
sudo dnf install -y smartmontools nvme-cli jq
  • smartmontools 提供 smartctlsmartd
  • nvme-cli 提供 nvme 命令。
  • jq 用于解析 nvme smart‑log 的 JSON 输出。

枚举设备

sudo smartctl --scan-open

典型输出:

/dev/sda -d sat # /dev/sda, ATA device
/dev/nvme0 -d nvme # /dev/nvme0, NVMe device

保留扫描输出中的 -d 类型;它可以避免在某些控制器上出现模糊探测。

健康检查脚本

将以下内容保存为 /usr/local/sbin/check-disk-health.sh 并赋予可执行权限。

#!/usr/bin/env bash
set -euo pipefail

LOG_TAG="disk-health-check"
RC=0

log() {
  systemd-cat -t "$LOG_TAG" echo "$*"
}

# Returns 0 when healthy enough, non‑zero when warning/failure bits are present.
check_smart() {
  local dev="$1"
  local dtype="$2"

  # -H overall health, -A attributes, -l error/selftest logs
  if smartctl -H -A -l error -l selftest -d "$dtype" "$dev" >/tmp/smart-${dev##*/}.log 2>&1; then
    log "OK SMART: $dev ($dtype)"
  else
    local c=$?
    log "WARN SMART: $dev ($dtype) exit=$c"
    log "DETAIL SMART: $(tail -n 5 /tmp/smart-${dev##*/}.log | tr '\n' ' ' | sed 's/  */ /g')"
    RC=1
  fi
}

check_nvme() {
  local dev="$1"

  if out=$(nvme smart-log "$dev" -o json 2>/dev/null); then
    cw=$(printf '%s' "$out" | jq -r '.critical_warning // 0')
    temp_k=$(printf '%s' "$out" | jq -r '.temperature // empty')
    used=$(printf '%s' "$out" | jq -r '.percentage_used // empty')

    if [[ "$cw" != "0" ]]; then
      log "WARN NVMe: $dev critical_warning=$cw percentage_used=${used:-n/a} temperature(K)=${temp_k:-n/a}"
      RC=1
    else
      log "OK NVMe: $dev percentage_used=${used:-n/a} temperature(K)=${temp_k:-n/a}"
    fi
  else
    log "WARN NVMe: failed to read smart-log for $dev"
    RC=1
  fi
}

main() {
  command -v smartctl >/dev/null || { echo "smartctl missing"; exit 2; }
  command -v nvme >/dev/null || { echo "nvme-cli missing"; exit 2; }
  command -v jq >/dev/null || { echo "jq missing (install jq)"; exit 2; }

  mapfile -t scanned
}
  • 脚本会使用标签 disk-health-check 将结果记录到 systemd-journald
  • 若任何设备报告警告,脚本将以非零状态退出。

参考资料

  • systemd.timer(5)
  • nvme-smart-log(1)
  • Debian smartmontools 软件包详情
  • ArchWiki S.M.A.R.T. 操作说明
0 浏览
Back to Blog

相关文章

阅读更多 »