Skip to content

Instantly share code, notes, and snippets.

@KekTuSx
Last active August 23, 2022 10:44
Show Gist options
  • Save KekTuSx/84037efc6fd2d88f02a13f715279748f to your computer and use it in GitHub Desktop.
Save KekTuSx/84037efc6fd2d88f02a13f715279748f to your computer and use it in GitHub Desktop.
A bash script that checks all connected disks with Smartmontools short test.
#!/bin/bash
#
# Checks all connected disks for errors with smartmontools
# Variables
###########
date=null # time for logs
diskcount=$(lsblk -l | grep -c 'disk') # counts all connected disks
disklist=$(lsblk -l | grep 'disk' | grep -oh "[[:alpha:]]*sd[[:alpha:]]*") # create a list of all connected disks https://stackoverflow.com/a/15997066
## Arrays
#########
declare -A pkgman
pgkman[apt]=$(which apt)
pkgman[yum]=$(which yum)
pkgman[pacman]=$(which pacman)
# Functions
###########
# Checks if a test is currently running on a drive through smartctl --capabilities
test_progress() {
smartctl -c /dev/"$disk" | grep -A 1 "Self-test routine in progress"
}
# Outputs to sdout and log file
append_log(){
tee -a log.txt
}
# Function for SIGINT trap; see below
interrupt() {
smartctl -X /dev/"$disk"
exit
}
# Script
########
# Install smartmontools if not installed
for i in "${!pkgman[@]}" # takes index of array
do
# apt (debian, ubuntu, mint...)
if which "${pgkman[$i]}"; then # checks if the value (output of which) is not null
if [ "$i" = apt ]; then # if the current array index (type of package manager) is <some-package-manager>
if dpkg -s smartmontools | grep -q "install ok installed"; then
echo -e "\nSmartmontools already installed"
else
echo -e "\nInstalling Smartmontools"
apt update
apt install smartmontools
fi
fi
# rpm/yum (redhat, opensuse, fedora, centos...)
if [ "$i" = yum ]; then
if yum list installed | grep -q "smartmontools"; then
echo -e "\nSmartmontools already installed"
else
echo -e "\nInstalling Smartmontools"
yum update
yum install smartmontools
fi
fi
# pacman (arch, manjaro...)
if [ "$i" = pacman ]; then
if pacman -Qs smartmontools > /dev/null; then
echo -e "\nSmartmontools already installed"
else
echo -e "\nInstalling Smartmontools"
pacman -Syy
pacman -S smartmontools
fi
fi
fi
done
# Creates or wipes log file
echo > log.txt
# Outputs number of connected disks
echo -e "\n\nNumber of connected disks:" | append_log
echo "$diskcount" | append_log
# Outputs names of connected disks
echo -e "\nAll connected disks:" | append_log
echo "$disklist"
read -n 1 -s -r -p "Press any key to commence testing"
# Cancels ongoing test when 'Ctrl-C' is pressed before exiting
trap interrupt SIGINT
# Iterate over every disk
for disk in $disklist
do
echo -e "\n#################### DISK $disk START ####################" | append_log
# Run a short offline test on disk
smartctl -t short /dev/"$disk" | grep -A 5000 "==="
# Adds timestamp to log
date=$(date)
echo -e "\nTest started $date\n" | append_log
while true
do
sleep 15s
if test_progress # cant tee here or it hangs when the test is complete
then
test_progress >> log.txt
smartctl -a /dev/"$disk" >> /dev/null # should keep the drives awake https://superuser.com/a/1294266
else
# Writes all test results to log file with a timestamp
# latest result is the first one; num 1
date=$(date)
echo -e "\nTest completed at $date\n" | append_log
smartctl -l selftest /dev/"$disk" | grep -A 5000 "===" | append_log
echo "******************** DISK $disk END ********************" | append_log
break
fi
done
done
echo -e "\n\n##################### TESTING FINISHED #############################" | append_log
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment