Skip to content

Instantly share code, notes, and snippets.

@hdavid0510
Created May 25, 2025 08:14
Show Gist options
  • Save hdavid0510/513c63fc12c5dd8b7888a2efd8976104 to your computer and use it in GitHub Desktop.
Save hdavid0510/513c63fc12c5dd8b7888a2efd8976104 to your computer and use it in GitHub Desktop.
Get TBW of connected SSDs through smartctl
#!/bin/bash
# ANSI colors
TEXT_CYAN='\e[96m'
TEXT_YELLOW='\e[93m'
TEXT_DEFAULT='\e[0m'
# Common formatter for byte-related outputs
function format_bytes_written_and_rate() {
local BYTES_WRITTEN=$1
local POWER_ON_HOURS=$2
local MB_WRITTEN=$(echo "scale=3; ${BYTES_WRITTEN} / 1048576" | bc)
local GB_WRITTEN=$(echo "scale=3; ${BYTES_WRITTEN} / 1073741824" | bc)
local TB_WRITTEN=$(echo "scale=3; ${BYTES_WRITTEN} / 1099511627776" | bc)
echo -e "${TEXT_YELLOW}Data written${TEXT_DEFAULT}"
printf "%20s MB\n" "$(echo ${MB_WRITTEN} | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta')"
printf "%20s GB\n" "$(echo ${GB_WRITTEN} | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta')"
printf "%20s TB\n" "$(echo ${TB_WRITTEN} | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta')"
echo -e "${TEXT_YELLOW}Mean write rate${TEXT_DEFAULT}"
if [[ "${POWER_ON_HOURS}" =~ ^[0-9]+$ && "${POWER_ON_HOURS}" -ne 0 ]]; then
local MB_PER_HOUR=$(echo "scale=3; ${MB_WRITTEN} / ${POWER_ON_HOURS}" | bc)
printf "%20s MB/hr\n" "$(echo ${MB_PER_HOUR} | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta')"
else
echo " N/A MB/hr"
fi
}
# Common function to print device info
function print_device_info() {
local DEVICE=$1
echo -e "${TEXT_CYAN}"
fdisk -l "${DEVICE}" | grep -i "model"
echo -e -n "${TEXT_DEFAULT}"
fdisk -l "${DEVICE}" | grep "${DEVICE}"
}
function print_tbw_sata() {
local DEV=$1
if [ -z "${DEV}" ]; then echo "No SATA SSD drive specified."; return 1; fi
if ! test -b "${DEV}"; then echo "Cannot find SATA SSD drive ${DEV}."; return 2; fi
local SMART_INFO=$(/usr/sbin/smartctl -A "${DEV}")
local POWER_ON_HOURS=$(echo "${SMART_INFO}" | grep "Power_On_Hours" | awk '{print $10}')
local WEAR_COUNT=$(echo "${SMART_INFO}" | grep "Wear_Leveling_Count" | awk '{print $4}' | sed 's/^0*//')
local LBAS_WRITTEN=$(echo "${SMART_INFO}" | grep "Total_LBAs_Written" | awk '{print $10}')
local BYTES_WRITTEN=$(echo "${LBAS_WRITTEN} * 512" | bc)
print_device_info "${DEV}"
echo -e "${TEXT_YELLOW}On time${TEXT_DEFAULT}"
printf "%20s hr\n" "$(echo ${POWER_ON_HOURS} | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta')"
format_bytes_written_and_rate "${BYTES_WRITTEN}" "${POWER_ON_HOURS}"
echo -e "${TEXT_YELLOW}Drive health${TEXT_DEFAULT}"
if [[ "${WEAR_COUNT}" =~ ^[0-9]+$ ]]; then
printf "%20s WEAR_COUNT\n" "${WEAR_COUNT}"
else
echo " N/A WEAR_COUNT"
fi
echo ""
}
function print_tbw_nvme() {
local DEV=$1
if [ -z "${DEV}" ]; then echo "No NVMe device specified."; return 1; fi
if ! test -b "${DEV}"; then echo "Cannot find NVMe device ${DEV}."; return 2; fi
local SMART_INFO=$(/usr/sbin/smartctl -x -d nvme "${DEV}")
local POWER_ON_HOURS=$(echo "${SMART_INFO}" | grep -i "Power On Hours" | awk -F: '{gsub(/ /, "", $2); gsub(/,/, "", $2); print $2}')
local DATA_UNITS_WRITTEN=$(echo "${SMART_INFO}" | grep -i "Data Units Written" | awk -F: '{gsub(/[^0-9]/, "", $2); print $2}')
local PERCENTAGE_USED=$(echo "${SMART_INFO}" | grep -i "Percentage Used" | awk -F: '{gsub(/[^0-9]/, "", $2); print $2}')
if [[ -z "${DATA_UNITS_WRITTEN}" || -z "${POWER_ON_HOURS}" ]]; then
echo "SMART data missing or unreadable for ${DEV}"
return 3
fi
local BYTES_WRITTEN=$(echo "${DATA_UNITS_WRITTEN} * 512" | bc)
print_device_info "${DEV}"
echo -e "${TEXT_YELLOW}On time${TEXT_DEFAULT}"
printf " %20s hr\n" "$(echo ${POWER_ON_HOURS} | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta')"
format_bytes_written_and_rate "${BYTES_WRITTEN}" "${POWER_ON_HOURS}"
echo -e "${TEXT_YELLOW}Drive health${TEXT_DEFAULT}"
if [[ "${PERCENTAGE_USED}" =~ ^[0-9]+$ ]]; then
printf "%20s %%\n" "$((100 - PERCENTAGE_USED))"
else
echo " N/A %"
fi
echo ""
}
# List of drives to check
for ssd in /dev/sd[a-z] /dev/nvme*n1; do
if [[ -b "$ssd" ]]; then
if [[ "$ssd" == /dev/nvme* ]]; then
print_tbw_nvme "$ssd"
else
print_tbw_sata "$ssd"
fi
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment