2020-12-30 19:06:16 +01:00
#!/bin/bash
2022-04-18 18:08:22 +02:00
OUTPUT = ( $( lsscsi -g | grep "disk" | grep -v "Virtual Disk" | grep -o "/dev/sg[0-9]" | paste -sd ' ' ) ) #Liste des disques non virtuels
DISKS = ( ) #Array vide dans lequel on mettra les disques a tester
TEMPS_SHORT = ( ) #Array vide dans lequel on va mettre les temps de polling short
TEMPS_LONG = ( ) #Array vide dans lequel on va mettre les temps de polling long
ARRAY_TEMPS = ( ) #Creation d un array vide pour temps de selftest
AVANCEMENT = ( ) #Array pour le pourcentage du test restant sur chaque disque
LOG = ( $( eval echo ~$USER /SANTE_DISK) ) #Chemin du fichier de sortie du test (dans le repertoire home de l utilisateur)
PACKAGES = ( lsscsi smartmontools mailutils) #Liste des paquets necessaires
FIN_TEST = "NOK"
2022-04-16 17:52:49 +02:00
#Si votre fichier de script est appelé par cron et qu il contient un shell à la première ligne du type #!/Bin/bash , vous devez rechercher le nom parent-parent correspondant à vos besoins.
PPPID = ` ps h -o ppid = $PPID ` #Le PID parent est disponible dans bash en tant que variable $ PPID . La commande ps permettant d'obtenir le PID parent du PID parent
P_COMMAND = ` ps h -o %c $PPPID ` #On recupere le nom de la commande
if [ " $P_COMMAND " = = "cron" ] ; then
RUNNING_FROM_CRON = 1
else
RUNNING_FROM_CRON = 0
fi
2020-12-30 19:06:16 +01:00
for i in " ${ PACKAGES [@] } " #Verification et installation des paquets necessaires
do
2022-04-16 17:52:49 +02:00
if ! dpkg -s $i >/dev/null 2>& 1; then
echo "Installation du paquet " $i ""
apt install $i
fi
2020-12-30 19:06:16 +01:00
done
2021-01-29 12:13:04 +01:00
for i in " ${ OUTPUT [@] } " #Selection des disques ayant SMART a Enabled
do
2022-04-16 17:52:49 +02:00
if /usr/sbin/smartctl -i $i | grep "SMART support is: Enabled" >/dev/null 2>& 1; then
DISKS += ( $i )
fi
2021-01-29 12:13:04 +01:00
done
2022-04-18 18:08:22 +02:00
if [ " $1 " != "" ] ; then
TYPE_TEST = " $1 "
fi
if [ " $RUNNING_FROM_CRON " = = "0" ] ; then
while [ [ " $TYPE_TEST " != "short" && " $TYPE_TEST " != "long" ] ]
2022-04-16 17:52:49 +02:00
do
2022-04-18 18:08:22 +02:00
if [ " $TYPE_TEST " != "" ] ; then
echo " La durée du test entrée ( $TYPE_TEST ) est invalide. "
else
echo "Aucune durée de test entrée."
fi
read -p "Veuillez selectionner la durée du test (short ou long) : " TYPE_TEST
2022-04-16 17:52:49 +02:00
done
2022-04-18 18:08:22 +02:00
echo " Vous avez choisi le test $TYPE_TEST . "
for i in " ${ !DISKS[@] } " #Boucle de test sur l'INDEX de chaque disque (présence du ! )
do
DISK_MOUNT = " ${ DISKS [ $i ] } "
DUREE_TEST_POLLING = ( $( /usr/sbin/smartctl -c " $DISK_MOUNT " | grep "polling" | grep -Eo '[0-9]{1,}' | paste -sd ' ' ) ) #Extraction des temps de polling dans les capacites SMART du disque (seulement le chiffre, en minutes).
TEMPS_SHORT[ $i ] = " ${ DUREE_TEST_POLLING [0] } " #Alimentation de l'array pour les temps courts
TEMPS_LONG[ $i ] = " ${ DUREE_TEST_POLLING [1] } "
done
for i in " ${ !DISKS[@] } "
do
DISK_MOUNT = " ${ DISKS [ $i ] } "
if [ " $TYPE_TEST " = = "short" ] ; then
DUREE_TEST = " ${ TEMPS_SHORT [ $i ] } "
else
DUREE_TEST = " ${ TEMPS_LONG [ $i ] } "
fi
2022-04-16 17:52:49 +02:00
ARRAY_TEMPS += ( $DUREE_TEST )
2022-04-18 18:08:22 +02:00
MODEL = ( $( /usr/sbin/smartctl -i $DISK_MOUNT | grep "Device Model:" | sed "s/Device Model: //g" ) )
echo " Le selftest pour le disque ${ MODEL [@] } ( $DISK_MOUNT ) prendra $DUREE_TEST minutes. " #Utilisation d'un Array pour MODEL afin de gérer les espaces
done
elif [ [ " $TYPE_TEST " != "short" && " $TYPE_TEST " != "long" ] ] ; then # Si lancé par Cron sans argument valide
" $TYPE_TEST " = long
fi
for i in " ${ DISKS [@] } " #Boucle de test sur chaque disque
do
/usr/sbin/smartctl -t " $TYPE_TEST " " $i " > /dev/null 2>& 1
2020-12-30 19:06:16 +01:00
done
2022-04-18 18:08:22 +02:00
2022-04-24 21:57:08 +02:00
TEMPS_MAX = 0 #RAZ du temps de polling
for i in " ${ ARRAY_TEMPS [@] } " #recherche de la valeur max dans les temps de polling extraits
do
if ( ( " $i " > $TEMPS_MAX ) )
then TEMPS_MAX = " $i "
fi
done
2022-04-16 17:52:49 +02:00
if [ " $RUNNING_FROM_CRON " = = "0" ] ; then
echo ""
2022-04-24 21:57:08 +02:00
fi
2020-12-30 19:06:16 +01:00
2022-04-24 21:57:08 +02:00
while [ " $FIN_TEST " = "NOK" ] #On boucle tant qu au moins un disque n a pas fini son selftest
do
ECRIRE = "FALSE"
FIN_TEST = "OK"
TEMPS = ( $( date +"%T" ) )
2021-01-29 18:12:29 +01:00
2022-04-24 21:57:08 +02:00
for i in " ${ !DISKS[@] } "
2022-04-16 17:52:49 +02:00
do
2022-04-24 21:57:08 +02:00
MODEL = ( $( /usr/sbin/smartctl -i ${ DISKS [ $i ] } | grep "Device Model:" | sed "s/Device Model: //g" ) )
if /usr/sbin/smartctl -c " ${ DISKS [ $i ] } " | grep "Self-test routine in progress" > /dev/null 2>& 1; then #Si scan non fini
FIN_TEST = "NOK" #On repasse la variable FIN_TEST a FALSE
POURCENT_EXT = ( $( /usr/sbin/smartctl -c " ${ DISKS [ $i ] } " | grep "% of test remaining" ) )
if [ " ${ POURCENT_RESTANT [ $i ] } " != " $POURCENT_EXT " ] ; then
POURCENT_RESTANT[ $i ] = " $POURCENT_EXT "
AVANCEMENT[ $i ] = " $TEMPS : $POURCENT_RESTANT du selftest restant sur le disque ${ MODEL [@] } ( ${ DISKS [ $i ] } ). "
ECRIRE = "TRUE" #On écrit seulement si changement sur au moins un disque
fi
else
AVANCEMENT[ $i ] = " $TEMPS : selftest terminé sur le disque ${ MODEL [@] } ( ${ DISKS [ $i ] } ). "
2022-04-16 17:52:49 +02:00
fi
done
2022-04-24 21:57:08 +02:00
if [ " $RUNNING_FROM_CRON " = = "0" ] ; then
2022-04-18 18:08:22 +02:00
if [ " $ECRIRE " = = "TRUE" ] ; then
echo ""
for i in " ${ !DISKS[@] } "
do
echo " ${ AVANCEMENT [ $i ] } "
done
2022-04-16 17:52:49 +02:00
fi
2022-04-24 21:57:08 +02:00
fi
sleep 5s #On attend pour relancer la boucle de test de statut
done
if [ " $RUNNING_FROM_CRON " = = "0" ] ; then
2022-04-18 18:08:22 +02:00
echo ""
for i in " ${ !DISKS[@] } " #Une fois qu'on est sur la fin du test pour l'ensemble des disques
do
echo " ${ AVANCEMENT [ $i ] } "
done
echo ""
2022-07-25 12:14:10 +02:00
count = $(( ( 50 - ` expr length $LOG ` - 4 ) / 2 )) #Bloc gerant le nombre de * intermédiaires suivant longueur du chemin du fichier log
text1 = ""
for ( ( i = 0; i < " $count " ; ++i ) )
do
text1 = " ${ text1 } * "
done
2022-07-26 23:19:36 +02:00
LONGUEURPATH = $(( ` expr length $LOG ` ))
2022-07-26 23:23:13 +02:00
if [ $(( $LONGUEURPATH % 2 )) -eq 0 ] ; then #Test si le nombre de caractère du [path + nom fichier] est paire
text2 = " $text1 " #si paire
else
text2 = " $text1 * "
fi
2022-07-25 12:14:10 +02:00
text = " $text1 $LOG $text2 "
printf '*%.0s' { 1..50} ; printf '\n'
2022-04-16 17:52:49 +02:00
echo "***** TESTS TERMINES ET LOG DISPONIBLE SOUS *****"
2022-07-25 12:14:10 +02:00
echo " $text "
printf '*%.0s' { 1..50} ; printf '\n'
2022-04-16 17:52:49 +02:00
echo ""
echo " Le test de l'ensemble des disques a pris $TEMPS_MAX minutes. "
fi
2022-04-24 21:57:08 +02:00
2021-01-26 00:31:37 +01:00
date > $LOG #RAZ fichier de sortie + inscription date
2021-01-28 18:52:41 +01:00
for i in " ${ DISKS [@] } " #Boucle d inscription des résultats dans le fichier de sortie
2020-12-30 19:06:16 +01:00
do
2022-04-24 21:57:08 +02:00
echo "----------------------------------------------------------------" >> $LOG
echo "DISK " $i "" >> $LOG
/usr/sbin/smartctl -i " $i " | grep "Model Family" >> $LOG
/usr/sbin/smartctl -i " $i " | grep "Device Model" >> $LOG
/usr/sbin/smartctl -i " $i " | grep "Serial Number" >> $LOG
/usr/sbin/smartctl -i " $i " | grep "Firmware" >> $LOG
echo " " >> $LOG
/usr/sbin/smartctl -H -A -l selftest " $i " >> $LOG
echo " " >> $LOG
2020-12-30 19:06:16 +01:00
done
2022-04-16 17:52:49 +02:00
if [ " $RUNNING_FROM_CRON " = = "1" ] ; then
cat $LOG | /usr/bin/mailx -s " Sante des disques sur $HOSTNAME " root@$HOSTNAME #envoi de mail
2022-04-24 21:57:08 +02:00
fi