Script pour imprimer ou stocker un descriptif de toutes vos partitions
De Wiki de la communauté Mandriva.
Examinant le partitionnement de mon système avec Gparted, j'ai été agacé de devoir tout noter sur un bout de papier avant de me lancer dans une nouvelle installation : Gparted n'offre pas de fonction d'impression. Je me suis pris à rêver d'un petit script qui imprimerait un maximum d' informations pertinentes concernant les partitions du système.
Vous trouverez ci-dessous un tel script. Très utile lorsque vous serez en pleine phase de repartionnement de vos disques ou d'installation d'un nouvel OS sur votre machine.
La description des fonctionnalités de ce script se trouve en commentaires (ligne commençant par un dièse #) au début du code ci-dessous.
À noter !
Il n'est pas nécessaire de comprendre un script pour l'utiliser ! Bien que cela ne nuise pas ;-)
Il n'est pas nécessaire de comprendre un script pour l'utiliser ! Bien que cela ne nuise pas ;-)
Petit guide d'utilisation
- Ouvrez un éditeur de texte (gedit, kwrite ou tout autre : vous devriez en trouver dans le menu des applications de votre bureau Linux).
- Sélectionnez le code du script ci-dessous de la première à la dernière ligne.
- Copiez la sélection (Contrôle-C).
- Allez dans l'éditeur.
- Collez la sélection (Contrôle-V) et vérifiez bien que le script a été collé de la première à la dernière ligne.
- Dans l'éditeur, enregistrez le fichier (essayez de vous rappeler dans quel répertoire vous le créez !), de préférence sous le nom de : scrute.sh.
- Ouvrez une console (vous en trouverez dans le menu des applications de votre bureau).
- Passez root ( su -).
- Rendez-vous dans le répertoire où se trouve le script (utilisez éventuellement la commande cd nom_du_repertoire ).
- Rendez le script exécutable par un chmod +x scrute.sh (ceci n'aura pas à être refait par la suite).
- Lancez le script par une commande ./scrute.sh
À noter !
Si vous êtes sous Ubuntu (et bien sûr en train de travailler sur vos partitions en vue d'installer une Mandriva...), le point 8 doit être omis; en 10 lancez la commande ainsi : sudo chmod +x scrute.sh et en 11 comme ceci : sudo ./scrute.sh
Si vous êtes sous Ubuntu (et bien sûr en train de travailler sur vos partitions en vue d'installer une Mandriva...), le point 8 doit être omis; en 10 lancez la commande ainsi : sudo chmod +x scrute.sh et en 11 comme ceci : sudo ./scrute.sh
Le code
Attention !
Dans cette version, le traitement des partitions occupées est correct. Le traitement des espaces disponibles entre partitions ou aux extrémités du disque est encore en cours de développement.
Dans cette version, le traitement des partitions occupées est correct. Le traitement des espaces disponibles entre partitions ou aux extrémités du disque est encore en cours de développement.
#! /bin/bash
# scrute.sh
# par jcl_vanier (larges contributions de Ptyxs et Gibé)
# mention spéciale à PapaJaac pour son travail de traduction en qt !
# forum Mandriva : http://forum.mandriva.com/fr/viewtopic.php?p=849628#p849628
# Attention : ce script se lance avec des droits de superutilisateur (sous root ou avec sudo).
# Ce script vous fournit des informations utiles sur les partitions de vos
# disques durs internes et des disques externes branchés.
# Il effectue un test de santé rapide smart sur l'état de vos disques
# et en affiche les résultats (seulement si les smartmontools sont installés sur votre machine).
# A l'exécution, les informations sont d'abord pour la plupart affichées en console,
# ensuite, l'éditeur de texte ouvre un fichier temporaire contenant les informations complètes :
# vous pouvez vous borner à l'examiner tranquillement,
# vous pouvez l'imprimer (d'un clic sur l'icône ad hoc de l'éditeur)
# vous pouvez l'enregistrer, si vous le souhaitez, sous le nom que vous voulez.
# Le script se termine quand vous fermez l'éditeur de texte.
# Le fichier temporaire d'origine est alors détruit
# (mais pas la version que vous avez enregistrée - si vous avez choisi d'enregistrer).
###############################################################################
case $1 in
"")
DETAIL=""
;;
"-d")
DETAIL="oui"
;;
*)
echo "usage $0 [-d]"
echo "option -d : affichage détaillé"
exit 1
esac
EDITEUR=""
[[ -z "$EDITEUR" ]] && EDITEUR=$(which gedit 2> /dev/null)
[[ -z "$EDITEUR" ]] && EDITEUR=$(which kwrite 2> /dev/null)
[[ -z "$EDITEUR" ]] && EDITEUR=$(which kate 2> /dev/null)
[[ -z "$EDITEUR" ]] && EDITEUR=$(which vim 2> /dev/null)
[[ -z "$EDITEUR" ]] && EDITEUR=$(which vi 2> /dev/null)
[[ -z "$EDITEUR" ]] && EDITEUR=$(which emacs 2> /dev/null)
[[ -z "$EDITEUR" ]] && EDITEUR=$(which ooffice 2> /dev/null)
[[ -z "$EDITEUR" ]] && EDITEUR=$(which kword 2> /dev/null)
TMPDIR=/tmp
TMPDIR_SAV=/root
RESULTAT=$(mktemp -t resultat.XXXXX)
FICTEMP=$(mktemp -t fictemp.XXXXX)
POINT_MONT_TEMP=$(mktemp -d -t reptemp.XXXXX)
SMARTCTL=/usr/sbin/smartctl
NB_SECTEURS_MINIMAL=2048 # nombre de secteurs mini d'une zone entre partitions pour sortie simplifiée ==> minimum: 1 Mo
###############################################################################
trap sortie EXIT
function sortie() {
echo "suppression de $RESULTAT"
/bin/rm $RESULTAT
echo "suppression de $FICTEMP"
/bin/rm $FICTEMP
### La commande rm est potentiellement dangereuse
### C'est pourquoi ces dernières lignes sont désactivées
### Néanmoins le test devrait garantir une certaine sécurité
### Vérifier avant de l'activer que le résultat de la commande du
### donne un résultat conforme à ceci:
### $ du -s dossier_temporaire
### $ 0 dossier_temporaire
# pour assurer le démontage
umount -l $POINT_MONT_TEMP 2> /dev/null
# if [ "$(du -s $POINT_MONT_TEMP | grep $POINT_MONT_TEMP | cut -f 1 )" == "0" ]
# then
# echo "suppression de $POINT_MONT_TEMP"
# /bin/rm -R $POINT_MONT_TEMP
# else echo "Maintien de $POINT_MONT_TEMP"
# fi
echo -e "\nbye\n"
}
###############################################################################
# fonction partition
# traite les paramètres d'une partition
# Requiert $DEV $TAILLE_SECTEUR
# Rend $SECT_DEBUT_ZONE $SECT_FIN_ZONE $SECT_FIN_ZONE_PREC
function partition() {
local DEV=$1
local TAILLE_SECT=$2
local SECT_DEBUT
local SECT_FIN
local NBSECTEURS
MONT_TEMP="non" # on n'a pas encore effectué de montage temporaire
# Traitement de blkid
if [ -n "$( fdisk -l | grep -e "^$DEV" | grep -i Etendue)" ]
then
echo " Partition étendue" >> $RESULTAT
else
LABEL="" ; UUID="" ; FILESYS=""
BLKID=$(blkid $DEV)
CHAMP1=$(echo $BLKID | awk -F '[:\"] ' '{print $2}' | sed s/\"//g)
CHAMP2=$(echo $BLKID | awk -F '[:\"] ' '{print $3}' | sed s/\"//g)
CHAMP3=$(echo $BLKID | awk -F '[:\"] ' '{print $4}' | sed s/\"//g)
case "$(echo $CHAMP1 | grep -oE "^TYPE=|^LABEL=|^UUID=")" in
TYPE=)
FILESYS=$( echo $CHAMP1 | sed s/TYPE=//)
;;
LABEL=)
LABEL=$( echo $CHAMP1 | sed s/LABEL=//)
;;
UUID=)
UUID=$( echo $CHAMP1 | sed s/UUID=//)
esac
case "$(echo $CHAMP2 | grep -oE "^TYPE=|^LABEL=|^UUID=")" in
TYPE=)
FILESYS=$( echo $CHAMP2 | sed s/TYPE=//)
;;
LABEL=)
LABEL=$( echo $CHAMP2 | sed s/LABEL=//)
;;
UUID=)
UUID=$( echo $CHAMP2 | sed s/UUID=//)
esac
case "$(echo $CHAMP3 | grep -oE "^TYPE=|^LABEL=|^UUID=")" in
TYPE=)
FILESYS=$( echo $CHAMP3 | sed s/TYPE=//)
;;
LABEL=)
LABEL=$( echo $CHAMP3 | sed s/LABEL=//)
;;
UUID=)
UUID=$( echo $CHAMP3 | sed s/UUID=//)
esac
LABEL=${LABEL:-(none)}
if [ -z "$(df | grep "$DEV ")" ] # une partition non montée n'apparaît pas avec df
then
POINTMONT="(not mounted)"
if [ "$FILESYS" == "swap" ]
then if [ -n "$(swapon -s | grep -o $DEV)" ]
then POINTMONT="<swap>"
else echo "swap inactive"
fi
fi
else POINTMONT=$(df | grep "$DEV " | awk -F '%' '{ print $2}')
fi
if [[ ("$POINTMONT" == "(not mounted)") && ("$FILESYS" != "swap") ]]
then echo "montage temporaire de $DEV"
MONT_TEMP="oui"
mount -t "$FILESYS" "$DEV" "$POINT_MONT_TEMP"
fi
echo " Système de fichiers=$FILESYS Label="$LABEL" PdeMontage=$POINTMONT UUID=$UUID" | tee -a $RESULTAT
fi
#traitement de fdisk
# remplacement du caractère * par = pour éviter les ennuis liés à l'expansion
echo $(fdisk -lu | grep "$DEV " | tr \* =) > $FICTEMP
cat $FICTEMP
if [ -z "$(cat $FICTEMP | grep "=")" ]
then read DEV SECT_DEBUT SECT_FIN RESTE < $FICTEMP
DRAPEAU="(none)"
else read DEV DRAPEAU SECT_DEBUT SECT_FIN RESTE < $FICTEMP
DRAPEAU="boot"
fi
NBSECTEURS=$(($SECT_FIN - $SECT_DEBUT + 1))
echo -e " Secteur début=$SECT_DEBUT Secteur fin=$SECT_FIN Nombre de secteurs=$NBSECTEURS\n Drapeau=$DRAPEAU " >> $RESULTAT
echo " Taille de secteur=$TAILLE_SECTEUR octets" >> $RESULTAT
# traitement de df
echo $(df -h | grep "$DEV ") > $FICTEMP
if [ -z "$(cat $FICTEMP)" ]
# partition non montée
then
taille_calc $NBSECTEURS $TAILLE_SECTEUR
echo " Taille totale=$TAILLE_CALC" >> $RESULTAT
# partition montée
else read DEV TAILLE_TOT UTIL DISPO PROP_UTIL RESTE < $FICTEMP
echo " Taille totale=$TAILLE_TOT Utilisée=$UTIL ($PROP_UTIL) Disponible=$DISPO ""($((100-$(echo $PROP_UTIL | cut -d "%" -f 1 )))%)" >> $RESULTAT
fi
[[ "$MONT_TEMP" == "oui" ]] && $(umount -l $POINT_MONT_TEMP ; MONT_TEMP="non")
if [ -z "$( fdisk -l | grep -e "^$DEV" | grep -i Etendue)" ] # mise à jour du pointeur
then SECT_FIN_ZONE_PREC=$SECT_FIN
else SECT_FIN_ZONE_PREC=$(($SECT_DEBUT - 1)) # si partition étendue on reprend depuis le début de celle-ci
fi
SECT_DEBUT_ZONE=$SECT_DEBUT
SECT_FIN_ZONE=$SECT_FIN
}
###############################################################################
# Fonction taille_calc
# Calcule la taille d'une zone donnée en nombre de secteurs
# Requiert $NBSECTEURS et $TAILLE_SECTEUR
# Rend $TAILLE_CALC
function taille_calc() {
local NBSECTEURS=$1
local TAILLE_SECTEUR=$2
TAILLE_CALC=$(($NBSECTEURS * $TAILLE_SECTEUR))
if [ "${#TAILLE_CALC}" -gt "4" ]
then TAILLE_CALC="$(($TAILLE_CALC / 1024))"
if [ "${#TAILLE_CALC}" -gt "4" ]
then TAILLE_CALC="$(($TAILLE_CALC / 1024))"
if [ "${#TAILLE_CALC}" -gt "4" ]
then TAILLE_CALC="$(($TAILLE_CALC / 1024)) Go"
else TAILLE_CALC="$TAILLE_CALC Mo"
fi
else TAILLE_CALC="$TAILLE_CALC Ko"
fi
else TAILLE_CALC="$TAILLE_CALC octets"
fi
}
###############################################################################
# fonction type_zone
# tente d'analyser le contenu d'une zone non allouée
# Requiert $DEV $SECT_DEBUT $NBSECTEURS $TAILLE_SECTEUR
function type_zone() {
local DEV=$1
local DISQUE=$(echo $1 | sed s/[0-9]//g)
local SECT_DEBUT=$2
local NBSECTEURS=$3
local TAILLE_SECTEUR=$4
local TAILLE_ZONE=$(($NBSECTEURS * $TAILLE_SECTEUR))
[[ "$SECT_DEBUT" -eq 0 ]] && echo "Secteur 0 : MBR" | tee -a $RESULTAT
if [ -z "$(dd if=$DISQUE skip=$SECT_DEBUT bs=$TAILLE_SECTEUR count=1 2>/dev/null | hexdump -C |grep -ie "^000001f0" | awk '{print $16 $17}' | grep -io "55AA")" ] # présence du nombre magique ?
then echo "Espace réservé ou non alloué à une partition" | tee -a $RESULTAT
if [ $TAILLE_ZONE -le $(( $TAILLE_SECTEUR * 2048 )) ] # valeur arbitraire pour ne pas parcourir des zones trop étendues
then
if [ -z "$(dd if=$DISQUE skip=$SECT_DEBUT bs=$TAILLE_SECTEUR count=$NBSECTEURS 2>/dev/null | hexdump | tr "*" " " | awk -F '[ \n"]' '{print $2 $3 $4 $5 $6 $7 $8}' | grep -v "00")" ]
then echo " Espace vide" | tee -a $RESULTAT
fi
fi #[ $TAILLE_ZONE -le ...
else #on a le nombre magique
if [ "$SECT_DEBUT" -gt 0 ]
then echo "Espace racine (extended boot record) de $DEV" | tee -a $RESULTAT
else echo -e "Espace libre en début de disque après les tables de partitions\n (sur le premier secteur si MBR simple) \n (sur les premiers secteurs si MBR + GPT)" | tee -a $RESULTAT
fi
dd if=$DISQUE skip=$SECT_DEBUT bs=$TAILLE_SECTEUR count=1 2> /dev/null | grep -q "GRUB" && echo " GRUB a été trouvé" | tee -a $RESULTAT
dd if=$DISQUE skip=$SECT_DEBUT bs=$TAILLE_SECTEUR count=1 2> /dev/null | grep -q "LILO" && echo " LILO a été trouvé" | tee -a $RESULTAT
dd if=$DISQUE skip=$SECT_DEBUT bs=$TAILLE_SECTEUR count=1 2> /dev/null | grep -q "NTLDR" && echo " NTLDR (windows) a été trouvé" | tee -a $RESULTAT
dd if=$DISQUE skip=$SECT_DEBUT bs=$TAILLE_SECTEUR count=1 2> /dev/null | grep -q "BOOTMGR" && echo " BOOTMGR (windows) a été trouvé" | tee -a $RESULTAT
dd if=$DISQUE skip=$(($SECT_DEBUT + 1)) bs=$TAILLE_SECTEUR count=1 2> /dev/null | grep -q "EFI PART" && echo " Table de partition GUID a été trouvée" | tee -a $RESULTAT
fi #[ -z "$(dd if=$DISQUE ..."55AA"
}
###############################################################################
# function gap()
# calcule l'espace libre entre deux partitions
# Requiert SDEV $SECT_FIN_ZONE_PREC $TAILLE_SECTEUR $NB_SECTEURS_MINIMAL $DETAIL (dernier argument)
# Rend $SECT_DEBUT_ZONE $SECT_FIN_ZONE
function gap() {
local DEV=$1
local SECT_FIN_PREC=$2
local TAILLE_SECT=$3
local NB_SECT_MIN=$4
local DET=$5
local SECT_DEBUT
local SECT_FIN
local RESTE
echo $(fdisk -lu | grep "$DEV " | tr "\*" " ") > $FICTEMP
read D SECT_DEBUT SECT_FIN RESTE < $FICTEMP
if [ "$SECT_DEBUT" != "$(($SECT_FIN_PREC + 1))" ] # on a un trou entre deux partitions
then
NBSECTEURS=$(($SECT_DEBUT - $SECT_FIN_PREC))
taille_calc $NBSECTEURS $TAILLE_SECT
if [ $NBSECTEURS -gt $NB_SECT_MIN ] # on affiche les grandes zones
then
type_zone $DEV $(($SECT_FIN_PREC + 1)) $NBSECTEURS $TAILLE_SECT
echo " Secteur début=$(($SECT_FIN_PREC + 1)) Secteur fin=$(($SECT_DEBUT - 1)) Taille=$TAILLE_CALC" | tee -a $RESULTAT
echo -e '\n**************************************************************************\n' | tee -a $RESULTAT;
else
if [ -n "$DET" ] # si demandé, on affiche aussi les petites zones, typiquement les zones racines des partitions internes à la partition étendue
then
type_zone $DEV $(($SECT_FIN_PREC + 1)) $NBSECTEURS $TAILLE_SECT
echo " Secteur début=$(($SECT_FIN_PREC + 1)) Secteur fin=$(($SECT_DEBUT - 1)) Taille=$TAILLE_CALC" | tee -a $RESULTAT
echo -e '\n**************************************************************************\n' | tee -a $RESULTAT;
fi
fi
fi
SECT_DEBUT_ZONE=$SECT_DEBUT
SECT_FIN_ZONE=$SECT_FIN
}
###############################################################################
# fonction disque
# traite les paramètres du disque courant
# Requiert $DEV $DISQUE_PRECEDENT
# Rend $ DISQUE_COURANT $TAILLE_SECTEUR $SECT_FIN_ZONE_PREC
function disque() {
local DEV=$1
local DISQUE_PREC=$2
local DISQUE="$(echo $DEV | sed s/[0-9]//g)"
if [ "$DISQUE" != "$DISQUE_PREC" ] # on a changé de disque ce qui est toujours vrai au démarrage
then
fin_disque $DISQUE $DISQUE_PREC $SECT_FIN_PART
SECT_FIN_ZONE_PREC="-1"
TAILLE_SECTEUR=$(fdisk -lu | grep -A 2 "$DISQUE" | grep -ie "^Unit" | cut -d "=" -f 3 | cut -d " " -f 2)
echo "==========================================================================" | tee -a $RESULTAT
TAILLE_DISQUE=$(fdisk -l | grep -e "^Dis.*$DISQUE")
echo -e "Disque en cours de traitement:\n $TAILLE_DISQUE" | tee -a $RESULTAT
if [ -x $SMARTCTL ]
then
if [ -z "$($SMARTCTL -H $DISQUE -s on | grep -i -o "Unknown")" ] # on active smart pour le cas où il ne le serait pas déjà
then
SANTE="$($SMARTCTL -H $DISQUE | grep -E "overall-health |SMART Health Status:")"
echo " $SANTE" | tee -a $RESULTAT
if [ -z "$(echo $SANTE | grep -oE "PASSED|OK")" ]
then echo ">>>>>>>>>>> ATTENTION: LE DISQUE $DISQUE EST PEUT-ÊTRE EN TRAIN DE RENDRE L'ÂME <<<<<<<<<<<<<<" | tee -a $RESULTAT
else echo " Ce disque semble en bonne forme :-)" | tee -a $RESULTAT
fi
echo " Temps de fonctionnement: "$($SMARTCTL -A $DISQUE | grep "Power_On_Hours" | awk -F ' +' '{print $11}')" heures" | tee -a $RESULTAT
else echo " Type de disque inconnu de smartctl. Test de santé impossible !" | tee -a $RESULTAT
fi
fi
echo -e "==========================================================================\n" | tee -a $RESULTAT
fi
DISQUE_COURANT=$DISQUE
}
###############################################################################
# fonction fin_disque
# recherche une zone inocupée à la fin d'un disque
# Requiert $DISQUE_COURANT $DISQUE_PRECEDENT $SECT_FIN_PART_PRECEDENTE
# Modifie $DISQUE_PRECEDENT
function fin_disque() {
local DISQUE=$1
local DISQUE_PREC=$2
local SECT_FIN_PART_PREC=$3
local SECT_DEBUT
local SECT_FIN
if [ "$DISQUE" != "$DISQUE_PREC" ] # on a changé de disque ce qui est toujours vrai au démarrage
then
DISQUE_PRECEDENT=$DISQUE # on ajuste la variable globale
DISQUE=$DISQUE_PREC # on traite le disque précédent sauf si on en est au
if [ "$DISQUE" != "none" ] # sauf si on en est au premier disque
then
DERNIER_SECT_DISQUE=$(fdisk -lu $DISQUE | grep -e "cylind.*total" | sed s/".*total "//g | cut -d " " -f 1)
if [ "$DERNIER_SECT_DISQUE" != "$SECT_FIN_PART_PREC" ]
then # il reste un espace inutilisé
SECT_DEBUT=$(($SECT_FIN_PART_PREC + 1))
SECT_FIN=$DERNIER_SECT_DISQUE
NBSECTEURS=$(($SECT_FIN - $SECT_DEBUT))
taille_calc $NBSECTEURS $TAILLE_SECTEUR
# s'agit-il d'un espace de gestion, qui a été utilisé ou vide ?
type_zone $DISQUE $SECT_DEBUT $NBSECTEURS $TAILLE_SECTEUR
echo " Secteur début=$SECT_DEBUT Secteur fin=$SECT_FIN Taille=$TAILLE_CALC" | tee -a $RESULTAT
fi
echo -e '**************************************************************************\n' | tee -a $RESULTAT
fi
fi
}
###############################################################################
################ Début ########################################################
[[ "$UID" != "0" ]] && echo -e "ATTENTION : ce script doit être lancé avec des droits de superutilisateur (sous root ou avec sudo) !\n\n" && exit 1
echo "liste des partitions le $(date +"%A %d %B %G") à $(date +"%H h %M m %S s") : " | tee $RESULTAT
if [ -n "$DETAIL" ]
then echo "AFFICHAGE DÉTAILLÉ" | tee -a $RESULTAT
else echo -e "AFFICHAGE SIMPLIFIÉ\n Pour un affichage détaillé utilisez l'option -d" | tee -a $RESULTAT
fi
echo -e '**************************************************************************\n' | tee -a $RESULTAT;
DISQUE_PRECEDENT="none" # on n'a encore rien traité
# on trie d'abord par ordre alphabétique des disques puis par ordre de position physique des partitions selon le n° de leur premier secteur
for DEV in $(fdisk -l | grep -e "^/dev" | tr "\*" " " | sort -k 1,1.8 -k 2,2n | cut -d " " -f 1)
do
disque $DEV $DISQUE_PRECEDENT
gap $DEV $SECT_FIN_ZONE_PREC $TAILLE_SECTEUR $NB_SECTEURS_MINIMAL $DETAIL
echo "Partition : $DEV" >> $RESULTAT;
partition $DEV $SECT_FIN_ZONE_PREC $TAILLE_SECTEUR
SECT_FIN_PART=$SECT_FIN_ZONE
echo -e '\n**************************************************************************\n' | tee -a $RESULTAT;
done
fin_disque "disque-fictif" $DISQUE_PRECEDENT $SECT_FIN_PART
# Affichage dans un éditeur
if [ -n "$EDITEUR" ]; then
$EDITEUR $RESULTAT
else
echo "Aucun editeur détecté !"
read -p "Voulez-vous enregistrer le document ? (O/n) " REP
if [ -z $REP ] || [ $(echo $REP | grep -E "[Oo]ui|[Oo]$") ]
then
SCRUTE=$(mktemp --tmpdir=$TMPDIR_SAV scrute.XXXXX)
cat $RESULTAT > $SCRUTE
echo "Document disponible ici: $SCRUTE"
fi
fi
exit 0 # trap lance ici la fonction sortie()

