Skip to content

Instantly share code, notes, and snippets.

@marshki
Last active November 9, 2024 16:30
Show Gist options
  • Save marshki/96fe72696f89f1b7533a2c93324368bc to your computer and use it in GitHub Desktop.
Save marshki/96fe72696f89f1b7533a2c93324368bc to your computer and use it in GitHub Desktop.
Parse SMART Monitor test results for bad sector count, drive info.
#!/usr/bin/env bash
#
# smarty_pants
#
# Parse SMART Monitor test results for bad sector count, drive info.
#
# Author: M. Krinitz <mjk235 [at] nyu [dot] edu>
# Date: 16-Jul-2021
# License: MIT
#
host="$(hostname --fqdn)"
timestamp="$(date +"%b %d %X")"
to=""
cc=""
from=""
subject="SMART_Test_Results@$host"
mail_cmd="mail -s $subject -r $from -c $cc $to"
# Glob regex apptern match to find hard disk drive(s)--HDD(s)--on array.
drives=(/dev/[sh]d[a-z]*)
# Check yo privilege.
root_check() {
if [ "$EUID" != "0" ] ; then
printf "%s\n" "Root privileges required. Exiting."
exit 1
fi
}
# Check if `smartctl` command exists on system.
smart_binary_check() {
if ! command -v smartctl &> /dev/null; then
printf "%s\n" "SMART Monitoring Tools NOT installed. Exiting."
exit 1
fi
}
# Check if HDD(s) have SMART capability.
smart_capability_check() {
if smartctl --info "$disk" \
| grep --word-regexp --ignore-case --quiet "device lacks SMART capability."; then
printf "%s\n" "$disk NOT SMART capable. Exiting."
exit 1
fi
}
# Enable SMART on drive.
smart_enable() {
smartctl --smart=on --quietmode=silent --device=ata "$disk"
}
# Parse SMART report for bad sector count. If count != zero (0), warn me.
smart_bad_sector_count() {
local count
count=$(smartctl --all --device=ata "$disk" | awk '/Reallocated_Sector_Ct/ {print $NF}')
if [ "$count" != "0" ] ; then
printf "%s\n" "SMART status:---WARNING!!!---$count BAD SECTORS DETECTED on: $disk!!!"
else
printf "%s\n" "SMART status: No problems detected on: $disk."
fi
}
# Parse SMART info for:
# Model Family, Device Model, Serial Number, User Capacity.
smart_info() {
printf "%s\n" ""
smartctl --info --device=ata "$disk" |sed -n '5,7p; 10p'
printf "%s\n" ""
}
# Get retrieval value.
exit_status() {
printf "%s\n" $retVal
if [[ $retVal -ne 0 ]]; then
printf "%s\n" "ACHTUNG!!! Something went wrong, homie."
else
printf "%s\n" "Done. Exiting @ $timestamp."
fi
}
# Wrapper function. Pipe standard ouput to email.
main() {
root_check
smart_binary_check
printf "%s\n" "SMART report for: $host@$timestamp"
for disk in "${drives[@]}"; do
printf "%s\n" "----------"
smart_capability_check
smart_enable
smart_bad_sector_count
smart_info
done
}
main "$@" | $mail_cmd
retVal=$?
exit_status
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment