You are not logged in.

#1 2025-01-30 19:31:57

Markus.N2
Member
From: Germany
Registered: 2013-08-22
Posts: 100

Show SSD health in conky

Hi,
I've created a little helper script to show the SSD health in conky, without the need of giving conky root privileges or using a setuid bit.
Dependencies: You need the smartmontools to be installed.

As you need root privileges to call smartcl, the script itself needs to run as root. It writes the status to a text file, which is then chown'ed to your user and displayed in conky. IMO, updating the status hourly is sufficient, so I've just created a symlink in /etc/cron/hourly to my script.

As I'm no expert in using S.M.A.R.T. data, I've just chosen what I considered to be a plausible hint to the health. Feel free to teach me what data would be better to show. :-)
What I chose is:

  • Overall status, translated "PASSED" to "OK" to save precious space

  • "critical warning" (whatever this is)

  • available percentage of spare

  • amount of data written so far

  • temperature

You need to adapt the script to your user name and your devices !!!

/root/bin/ssd_health.sh:

#!/bin/bash

param_index=0
debug_mode=0

while [ "${1}" != "" ]
do
  case "${1}" in
    -h | --help)
      echo "usage: ${0##*/} [-h | --help] [-d | --debug]"
      echo "       debug mode does not write output files."
      exit 0
      ;;
    -d | --debug)
      debug_mode=1
      ;;
    -*) # Any other option
      echo "ERROR: Unknown option: ${1}" >&2
      ;;
    *) # no option
      param_index=$[ ${param_index} + 1 ]
      case ${param_index} in
        *)
          echo "ERROR: Additional parameter: \"${1}\"" >&2
          ;;
      esac
      ;;
  esac
  shift
done

# !!! change user here !!!
user=markus

tempdir=/tmp
outdir=/home/${user}/temp

# Below are some examples for different SSD's (NVME and SATA).
#
# To adapt this to your devices, choose the closest match and adapt it,
# then comment out or delete the others.
# Check the output of "smartctl -x /dev/..."
# Sou can also show the status of multiple SSD's. If the are the same brand,
# you need to extend the naming scheme of the tempfiles and outfiles.



# Samsung NVME

tempfile_samsung=${tempdir}/smartctl_nvme0.txt
outfile_samsung=${outdir}/health_${tempfile_samsung#${tempdir}/smartctl_}
if [ ${debug_mode} -eq 0 -o ! -f ${tempfile_samsung} ]
then
  smartctl -x /dev/nvme0 >${tempfile_samsung}
fi
if [ ${debug_mode} -ge 1 ]
then
  echo "tempfile_samsung = ${tempfile_samsung}"
  echo "outfile_samsung  = ${outfile_samsung}"
fi

process_device_samsung() {
  local overall_txt="SMART overall-health self-assessment test result:"
  local critical_txt="Critical Warning:"
  local available_spare_txt="Available Spare:"
  local data_written_txt="Data Units Written:"
  local temperature_txt="Temperature Sensor 1:"

  local overall=`sed -ne "/${overall_txt}/ { s/${overall_txt} *//; s/PASSED/OK/; p }" ${1}`
  local critical=`sed -ne "/${critical_txt}/ { s/${critical_txt} *//; p }" ${1}`
  local available_spare=`sed -ne "/${available_spare_txt}/ { s/${available_spare_txt} *//; p }" ${1}`
  local data_written=`sed -ne "/${data_written_txt}/ { s/[^\\[]*\\[//; s/].*//; p }" ${1}`
  local temperature=`sed -ne "/${temperature_txt}/ { s/${temperature_txt} *//; s/ Celsius/°C/; p  }" ${1}`

  echo "${overall}  ${critical}  ${available_spare}  ${data_written}  ${temperature}"
}

# Sandisk Sata

if [ ${debug_mode} -eq 0 -o ! -f ${tempfile_sandisk} ]
then
  smartctl -x /dev/sda >${tempfile_sandisk}
fi
tempfile_sandisk=${tempdir}/smartctl_sda.txt
outfile_sandisk=${outdir}/health_${tempfile_sandisk#${tempdir}/smartctl_}
if [ ${debug_mode} -ge 1 ]
then
  echo "tempfile_sandisk = ${tempfile_sandisk}"
  echo "outfile_sandisk  = ${outfile_sandisk}"
fi

process_device_sandisk() {
  local overall_txt="SMART overall-health self-assessment test result:"
  local available_spare_txt="Perc_Avail_Resrvd_Space"
  local data_written_txt="Total_Writes_GiB"
  local temperature_txt="Temperature_Celsius"

  local overall=`sed -ne "/${overall_txt}/ { s/${overall_txt}//; s/PASSED/OK/; p }" ${1}`
  local available_spare=`sed -ne "/${available_spare_txt}/ { s/.*${available_spare_txt}.* //; s/\$/%/; p }" ${1}`
  local data_written=`sed -ne "/${data_written_txt}/ { s/.*${data_written_txt}.* //; s/].*//; p }" ${1}`
  local temperature=`sed -ne "/${temperature_txt}/ { s/ .Min\\/Max.*/°C/; s/.*${temperature_txt}.* //; p }" ${1}`
  echo "${overall}   ${available_spare}   ${data_written}   ${temperature}"
}

# In this section, also remove what you don't need:

if [ ${debug_mode} -ge 1 ]
then
  echo -n "Samsung:   "; process_device_samsung ${tempfile_samsung}
  echo -n "Sandisk:   "; process_device_sandisk ${tempfile_sandisk}
else
  rm -f ${outfile_samsung}
  process_device_samsung ${tempfile_samsung} >${outfile_samsung}
  chmod 644 ${outfile_samsung}
  chown ${user}:${user} ${outfile_samsung}

  rm -f ${outfile_sandisk}
  process_device_sandisk ${tempfile_sandisk} >${outfile_sandisk}
  chmod 644 ${outfile_sandisk}
  chown ${user}:${user} ${outfile_sandisk}
fi

And in you r .conkyrc, you need to add this:

${execi 10 cat /home/markus/temp/health_nvme0n1.txt }

and surround it with your format text or template.
Of course, you need to change path and/or user name accordingly. :-)

After adding the symlink to cron, you need to run it manually at least once in order to have something to show in conky.
If you put the outfile(s) on a tmpfs, you also won't have an output between system boot and the next full hour. At least, conky won't crash if the "execi" fails.
To fix this, you can create a systemd service that runs once after boot and call the script from there additionally.

Offline

Board footer

Powered by FluxBB