获取硬盘当前温度的脚本

·

必须要root权限执行,温度数字会根据温度情况变色。

#!/bin/bash

SCRIPT_PATH=$(realpath "$0")

if [[ $EUID -ne 0 ]]; then
    sudo "$SCRIPT_PATH" "$@"
    exit $?
fi

export LC_ALL=C.UTF-8
export LANG=C.UTF-8

WARM=48
HOT=55

get_term_width() {
    local w
    w=$(tput cols 2>/dev/null)
    if [[ -z "$w" || ! "$w" =~ ^[0-9]+$ || "$w" -lt 80 ]]; then
        w=120
    fi
    echo "$w"
}

print_line() {
    local cols
    cols=$(get_term_width)
    printf '%*s\n' "$cols" '' | tr ' ' '-'
}

format_hours() {
    local hours="$1"

    if [[ -z "$hours" || "$hours" == "?" || ! "$hours" =~ ^[0-9]+$ ]]; then
        echo "?"
        return
    fi

    local days=$((hours / 24))
    local rem_hours=$((hours % 24))
    echo "${days}d ${rem_hours}h"
}

print_line
echo "HDD Temperature Monitor  $(date)"
print_line

# 重新规划列宽,去掉多余的占位列
printf "%-4s %-9s %-9s %-20s %-15s %-6s %-9s %-24s\n" \
"No" "Device" "Temp(°C)" "Model" "Serial" "FW" "Size" "Hours"

print_line

COUNT=0

for d in /dev/sd?; do
    [ -e "$d" ] || continue

    INFO=$(smartctl -i "$d" 2>/dev/null)
    ATTR=$(smartctl -A "$d" 2>/dev/null)

    MODEL=$(echo "$INFO" | awk -F: '
        /Device Model|Product/ {
            gsub(/^[ \t]+/, "", $2)
            print $2
            exit
        }
    ')

    if echo "$MODEL" | grep -qiE "QEMU|VBOX|VMware"; then
        continue
    fi

    COUNT=$((COUNT + 1))

    SERIAL=$(echo "$INFO" | awk -F: '
        /Serial Number/ {
            gsub(/^[ \t]+/, "", $2)
            print $2
            exit
        }
    ')

    FW=$(echo "$INFO" | awk -F: '
        /Firmware Version/ {
            gsub(/^[ \t]+/, "", $2)
            print $2
            exit
        }
    ')

    SIZE_DISPLAY=$(echo "$INFO" | awk '
        /User Capacity:/ {
            if (match($0, /\[[^]]+\]/)) {
                s = substr($0, RSTART + 1, RLENGTH - 2)
                print s
                exit
            }
        }
    ')
    [ -z "$SIZE_DISPLAY" ] && SIZE_DISPLAY="?"

    TEMP=$(echo "$ATTR" | awk '
        /Temperature_Celsius|Temperature_Internal/ {
            print $10
            exit
        }
    ')

    HOURS=$(echo "$ATTR" | awk '
        /Power_On_Hours/ {
            print $10
            exit
        }
    ')

    [ -z "$TEMP" ] && TEMP="?"
    [ -z "$HOURS" ] && HOURS="?"

    HUMAN_HOURS=$(format_hours "$HOURS")
    HOURS_DISPLAY="${HOURS} (${HUMAN_HOURS})"

    # 1. 打印序号和设备名
    printf "%-4s %-9s " "$COUNT" "$d"

    # 2. 打印带颜色的温度列,并精准计算对齐所需的空格
    if [[ "$TEMP" =~ ^[0-9]+$ ]]; then
        if (( TEMP >= HOT )); then
            printf '\e[41m%s\e[0m' "$TEMP"   # 红底白字 (CRITICAL)
        elif (( TEMP >= WARM )); then
            printf '\e[33m%s\e[0m' "$TEMP"   # 黄字 (WARNING)
        else
            printf '\e[32m%s\e[0m' "$TEMP"   # 绿字 (OK)
        fi

        # 补齐空格,保持总宽度为 9
        PAD_LEN=$(( 9 - ${#TEMP} ))
        if (( PAD_LEN > 0 )); then
            printf "%*s" "$PAD_LEN" ""
        fi
    else
        printf "%-9s" "?"
    fi

    # 3. 打印剩余信息
    printf "%-20.20s %-15.15s %-6.6s %-9.9s %-24.24s\n" \
        "$MODEL" \
        "$SERIAL" \
        "$FW" \
        "$SIZE_DISPLAY" \
        "$HOURS_DISPLAY"

done

print_line
echo "Total Drives: $COUNT"

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注