#!/usr/bin/env bash # Beschreibung: Überwacht die S.M.A.R.T Werte eines physikalischen Devices und gibt diese als XML in PRTG aus # Parameter: /dev/sda # Autor: Patrick Asmus # Web: https://www.techniverse.net # Version: 1.1 # Datum: 28.03.2025 # Modifikation: Grenzwerte hinzugefuegt ##################################################### DEVICE="$1" if [ -z "$DEVICE" ]; then echo "1Kein Gerät angegeben" exit 1 fi if ! command -v smartctl &>/dev/null; then echo "1smartctl nicht installiert" exit 1 fi if [ ! -b "$DEVICE" ]; then echo "1Gerät $DEVICE nicht gefunden" exit 1 fi SMART_OUTPUT=$(sudo smartctl -x "$DEVICE") # Herstellerinformationen extrahieren MODEL=$(echo "$SMART_OUTPUT" | awk -F: '/Model Number|Device Model/ {print $2}' | xargs) SERIAL=$(echo "$SMART_OUTPUT" | awk -F: '/Serial Number/ {print $2}' | xargs) VENDOR=$(echo "$SMART_OUTPUT" | awk -F: '/Vendor/ {print $2}' | xargs) [ -z "$VENDOR" ] && VENDOR=$(echo "$MODEL" | awk '{print $1}') MODEL=${MODEL:-Unbekanntes Modell} SERIAL=${SERIAL:-Keine Seriennummer} VENDOR=${VENDOR:-Unbekannter Hersteller} # Gerätetyp erkennen if echo "$SMART_OUTPUT" | grep -q "NVMe Version"; then TYPE="nvme" else TYPE="sata" fi XML="" if [ "$TYPE" = "sata" ]; then get_value() { echo "$SMART_OUTPUT" | awk -v id="$1" '$1 == id {print $10}' } TEMP=$(get_value 194) HOURS=$(get_value 9) REALLOC=$(get_value 5) REALLOC_EVENT=$(get_value 196) PENDING=$(get_value 197) UNCORRECTABLE=$(get_value 198) CRC_ERROR=$(get_value 199) REPORTED_UNCORRECT=$(get_value 187) for var in TEMP HOURS REALLOC REALLOC_EVENT PENDING UNCORRECTABLE CRC_ERROR REPORTED_UNCORRECT; do eval "[ -z \$$var ] && $var=0" done XML+=" Temperature (°C)$TEMPTemperature14555 Power-On Hours$HOURSHours Reallocated Sectors$REALLOCCount110 Reallocated Events$REALLOC_EVENTCount Pending Sectors$PENDINGCount11 Offline Uncorrectable$UNCORRECTABLECount11 Reported Uncorrect$REPORTED_UNCORRECTCount CRC Error Count$CRC_ERRORCount $VENDOR | $MODEL | SN: $SERIAL | $DEVICE" elif [ "$TYPE" = "nvme" ]; then get_nvme_value() { echo "$SMART_OUTPUT" | grep -E "^$1:" | head -n1 | awk -F: '{gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2}' } TEMP=$(get_nvme_value "Temperature" | awk '{print $1}') HOURS=$(get_nvme_value "Power On Hours" | sed 's/\.//g') PERCENT_USED=$(get_nvme_value "Percentage Used" | sed 's/%//') MEDIA_ERRORS=$(get_nvme_value "Media and Data Integrity Errors") ERROR_LOGS=$(get_nvme_value "Error Information Log Entries") UNSAFE_SHUTDOWNS=$(get_nvme_value "Unsafe Shutdowns") WARN_TEMP_TIME=$(get_nvme_value "Warning Comp. Temperature Time") CRIT_TEMP_TIME=$(get_nvme_value "Critical Comp. Temperature Time") POWER_CYCLES=$(get_nvme_value "Power Cycles") WRITTEN_TB=$(get_nvme_value "Data Units Written" | grep -o '\[[0-9.]* TB\]' | tr -d '[]TB ') READ_TB=$(get_nvme_value "Data Units Read" | grep -o '\[[0-9.]* TB\]' | tr -d '[]TB ') # === Wear Level Verlauf verfolgen === CACHE_FILE="/var/prtg/scriptsxml/.smart_wear_${DEVICE//\//_}.cache" NOW_DATE=$(date '+%Y-%m-%d') if [ -f "$CACHE_FILE" ]; then LAST_LEVEL=$(awk -F: '{print $1}' "$CACHE_FILE") LAST_DATE=$(awk -F: '{print $2}' "$CACHE_FILE") DIFF=$((PERCENT_USED - LAST_LEVEL)) if [ "$DIFF" -ne 0 ]; then TREND=" – +$DIFF % seit $LAST_DATE" echo "$PERCENT_USED:$NOW_DATE" > "$CACHE_FILE" else TREND=" – unverändert seit $LAST_DATE" fi else echo "$PERCENT_USED:$NOW_DATE" > "$CACHE_FILE" TREND=" – erster Messpunkt" fi for var in TEMP HOURS PERCENT_USED MEDIA_ERRORS ERROR_LOGS UNSAFE_SHUTDOWNS WARN_TEMP_TIME CRIT_TEMP_TIME POWER_CYCLES WRITTEN_TB READ_TB; do eval "[ -z \$$var ] && $var=0" done XML+=" Temperature (°C)$TEMPTemperature16580 Power-On Hours$HOURSHours Wear Level (Percentage Used)$PERCENT_USEDPercent17090 Power Cycles$POWER_CYCLESCount Media/Data Errors$MEDIA_ERRORSCount11 SMART Error Logs$ERROR_LOGSCount11050 Unsafe Shutdowns$UNSAFE_SHUTDOWNSCount Warning Temp Time$WARN_TEMP_TIMETimeSeconds Critical Temp Time$CRIT_TEMP_TIMETimeSeconds110 Data Written (TB)$WRITTEN_TBCustom Data Read (TB)$READ_TBCustom $VENDOR | $MODEL | SN: $SERIAL | $DEVICE | Wear: $PERCENT_USED %$TREND" else XML+="1Unbekannter Gerätetyp" fi XML+="" echo "$XML"