Skip to content

Instantly share code, notes, and snippets.

@ansemjo
Last active January 16, 2023 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ansemjo/d7144920167372be06a3 to your computer and use it in GitHub Desktop.
Save ansemjo/d7144920167372be06a3 to your computer and use it in GitHub Desktop.
script periodically polls drivestates with hdparm to show when drives go to sleep
#!/bin/bash
# The MIT License (MIT)
#
# Copyright (c) 2016 Anton Semjonov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# script to see when a drive goes to sleep / wakes up
is_num() { [ "$1" != "" ] && [[ $1 =~ ^[0-9]+$ ]] || { echo "'$1' is not a valid number."; exit 10; }; }
is_disk() { hdparm -I "$1" &>/dev/null || { echo "'$1' is not a valid drive for hdparm."; exit 11; }; }
timestamp() {
if [ "$starttime_epoch" == "" ]; then
starttime_epoch="$(date +%s)"
else
sec_since_start="$((($(date +%s)-$starttime_epoch)))"
clock_since_start="$(date -ud "@$sec_since_start" "+%Hh %Mm %Ss")"
echo -n "+ $clock_since_start"
fi
}
marker_active="█"
marker_sleeps="░"
marker_failed="╳"
get_drive_state() {
case $(hdparm -C "$1" 2>&1 | grep "drive state" | sed 's/ drive state is:[[:space:]]*//') in
"active/idle" ) echo -n "$marker_active$pad" ;;
"standby" ) echo -n "$marker_sleeps$pad" ;;
* ) echo -n "$marker_failed$pad" ;;
esac
}
#########
# help
if [ "$1" == "" ]; then
echo -e "$0 <cycle> <disks>\n <cycle> is the time in seconds between updates\n <disks> is a space-seperated list of disks to poll"
exit 99
fi
# get args
is_num "$1" && cycle="$1"
shift; disks=("$@");
if [ "$disks" != "" ]; then
command -v hdparm &>/dev/null || { echo "no access to 'hdparm'. try running as superuser?"; exit 13; }
for dsk in "${disks[@]}"; do is_disk "$dsk"; done
else echo "no disks given!"; exit 12; fi
# echo debug
echo "## cycle = $cycle seconds"
echo "## disks = $disks"
echo
# header
margin="$(printf "%40s")"
pad=" "
echo " $marker_active = active $marker_sleeps = standby $marker_failed = error"
disknum=0;
for dsk in "${disks[@]}"; do
echo -n "$margin"
((disknum++)); tmppos=1
while [ $tmppos -lt $disknum ]; do
echo -n "│$pad"; ((tmppos++)); done
echo "╭──╴$dsk"
done
echo -n "$margin"; tmppos=1
while [ $tmppos -le $disknum ]; do
echo -n "┷$pad"; ((tmppos++)); done
echo -ne "\n"
# get state
timestamp
while true; do
echo -n "$(date "+%F %T") ($(timestamp)) "
for disk in "${disks[@]}"; do get_drive_state "$disk"; done
echo
sleep $cycle
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment