180 lines
6.1 KiB
Bash
180 lines
6.1 KiB
Bash
#!/bin/bash
|
|
|
|
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"
|
|
|
|
#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
|
|
|
|
for i in "${PACKAGES[@]}" #Verification et installation des paquets necessaires
|
|
do
|
|
if ! dpkg -s $i >/dev/null 2>&1; then
|
|
echo "Installation du paquet "$i""
|
|
apt install $i
|
|
fi
|
|
done
|
|
|
|
for i in "${OUTPUT[@]}" #Selection des disques ayant SMART a Enabled
|
|
do
|
|
if /usr/sbin/smartctl -i $i | grep "SMART support is: Enabled" >/dev/null 2>&1; then
|
|
DISKS+=($i)
|
|
fi
|
|
done
|
|
|
|
if [ "$1" != "" ]; then
|
|
TYPE_TEST="$1"
|
|
fi
|
|
|
|
if [ "$RUNNING_FROM_CRON" == "0" ]; then
|
|
while [[ "$TYPE_TEST" != "short" && "$TYPE_TEST" != "long" ]]
|
|
do
|
|
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
|
|
done
|
|
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
|
|
ARRAY_TEMPS+=($DUREE_TEST)
|
|
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
|
|
done
|
|
|
|
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
|
|
|
|
if [ "$RUNNING_FROM_CRON" == "0" ]; then
|
|
echo ""
|
|
fi
|
|
|
|
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"))
|
|
|
|
for i in "${!DISKS[@]}"
|
|
do
|
|
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]})."
|
|
fi
|
|
done
|
|
|
|
if [ "$RUNNING_FROM_CRON" == "0" ]; then
|
|
if [ "$ECRIRE" == "TRUE" ];then
|
|
echo ""
|
|
for i in "${!DISKS[@]}"
|
|
do
|
|
echo "${AVANCEMENT[$i]}"
|
|
done
|
|
fi
|
|
fi
|
|
|
|
sleep 5s #On attend pour relancer la boucle de test de statut
|
|
done
|
|
|
|
if [ "$RUNNING_FROM_CRON" == "0" ]; then
|
|
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 ""
|
|
|
|
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
|
|
|
|
LONGUEURPATH=$((`expr length $LOG`))
|
|
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
|
|
|
|
text="$text1 $LOG $text2"
|
|
printf '*%.0s' {1..50}; printf '\n'
|
|
echo "***** TESTS TERMINES ET LOG DISPONIBLE SOUS *****"
|
|
echo "$text"
|
|
printf '*%.0s' {1..50}; printf '\n'
|
|
|
|
echo ""
|
|
echo "Le test de l'ensemble des disques a pris $TEMPS_MAX minutes."
|
|
fi
|
|
|
|
date > $LOG #RAZ fichier de sortie + inscription date
|
|
|
|
for i in "${DISKS[@]}" #Boucle d inscription des résultats dans le fichier de sortie
|
|
do
|
|
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
|
|
done
|
|
if [ "$RUNNING_FROM_CRON" == "1" ]; then
|
|
cat $LOG | /usr/bin/mailx -s "Sante des disques sur $HOSTNAME" root@$HOSTNAME #envoi de mail
|
|
fi |