#176 Le 07/04/2020, à 14:36
- ar barzh paour
Re : [Projet terminé] correction anomalie de grub
je voulais mettre une version plus à jour ici mais je n'arrive plus à relire les post 172 et 173 avec Firefox (j'ai déjà signalé cette anomalie mais non corrigée à ce jour)
modif_grub_v46_bis et recup_fstab_V8
corrige une anomalie concernant le label de la partition EFI (sans conséquence)
dans ces fichiers remplacer
if grep "LABEL" <<< $ligne par if grep " LABEL" <<< $ligne
if grep UUID <<< $ligne par if grep " UUID" <<< $ligne
if grepTYPE <<< $ligne par if grep " TYPE" <<< $ligne
if grep PARTUUID <<< $ligne par if grep " PARTUUID" <<< $ligne
PC : B760M DS3H DDR4, 12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : Intel(R) Core(TM)2 Duo CPU T6570 @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 22.04 ( en voyage )
Portable2 : T5750 @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )
Hors ligne
#177 Le 16/04/2020, à 17:27
- ar barzh paour
Re : [Projet terminé] correction anomalie de grub
avec Violent Monkey j'arrive maintenant à relire les post
donc pour ceux que ça intéresse ( je pense qu'il n'y a pas beaucoup de monde) voici la dernière version
/media/SH/grub/V46/modif_grub_V46_bis qui va de paire avec recup_fstab_v8
pour rappel modif_grub lance recup_fstab
que je poste dans les deux post suivants
PC : B760M DS3H DDR4, 12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : Intel(R) Core(TM)2 Duo CPU T6570 @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 22.04 ( en voyage )
Portable2 : T5750 @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )
Hors ligne
#178 Le 16/04/2020, à 17:29
- ar barzh paour
Re : [Projet terminé] correction anomalie de grub
pour rappel : il faut copier ce fichier ET le fichier (recup_fstab) du post suivant dans unrépertoire et lancer modif_grub
et il y aura création d'un fichier grub que l'on pourra analyser avant de remplacer l'original ! (au choix)
le fichier modif_grub_V46_bis
#!/bin/bash
nom_base=`echo $(basename $0)`
nom_dir=`echo $(dirname $0)`
echo "$nom_base"
echo "$nom_dir"
#########################################################################################
# résumé des actions effectuées
# modif_grub permet
# - de raccourcir la longueur d'un fichier au format grub
# en y supprimant des menus inutiles (menu contenant /dev /dev , uuid différents)
# le fichier à traiter doit contenir
# pemière ligne : un commentaire commençant par #
# la ligne : ### BEGIN /etc/grub.d/10_linux ###
#
# si la ligne : ### BEGIN /etc/grub.d/40_custom ### apparait
# seules les lignes entre 10_linux et 40_custom seront traitées
# si cette ligne n'apparait pas
# ce sont les lignes de 10_linux à la fin qui seront traitées
#
# un menu doit être de la forme
# menuentry ' ............ { ou menuentry " ..........{
# des lignes intermédiaires à priori quelconques
# la ligne terminant le menu ........ }
#
# aucun caractère [hors blancs] ne doit apparaître après un { ou un }
#
# un submenu doit être de la forme
# submenu '................{ ou submenu "................{
# des lignes quelconques ?
# de menus au format ci-dessus
# une ligne de fermeture ......} aucun caractères [hors blancs] après }
# si cette ligne fait partie d'un menu elle sera alors de la forme
# .........} }
#
# - d'ajouter un label à un menu de grub pour avoir une présentation plus claire
# pour cela deux solutions :
# - utilisation du label de la partition
# - utilisation d'un fichier personnel au format blkid
# chaque ligne devra commencée par /dev/xxx:
# chaque ligne devra contenir UUID=
# un caractère espace est nécessaire devant les champs utilisés
# ( LABEL UUID TYPE !!! )
# lorsqu'un label est modifié et que l'on retraite le fichier , ce label sera
# - l'action de remplacement d'un grub réel demande à l'utilisateur des précautions d'usage
# être capable de revenir en arrière si problème !
# c'est à dire être capable de remettre le grub d'origine
#########################################################################################
#########################################################################################
# les fichiers créés
# les fichiers créés par recup_fstab
# le fichier blkid-res.txt ( correspondance dev-uuid-label)
# le fichiers UBoot-UPart.txt ( cas des OS avec boot séparé)
# ce fichier est nécessaire (même vide) s'il est absent , le programme s'arêtera
# ZZZnum est un répertoire créée dans le répertoire courant
# les fichiers créés par recup_fstab dans ZZZnum
# le fichier DevSd-UBoot-UPart-<date> : contient les fichiers de /etc/fstab
# le fichier UBoot-UPart-<date>.txt : copie de UBoot-UPart.txt
#
# les autres fichiers qui sont créés dans ZZZnum par modif_grub
# le fichier grub-OK-<date>-<....>.txt destiné à remplacer le fichier traité
# ce fichier n'apparait plus si on a demandé le remplacement du fichier traité
# mais dans ce cas le fichier traité est sauvegardé (dans son nom-<date>)
# les fichiers suivants sont plus ou moins intéressant à analyser
# fichier grub-sup : contient les menus qui ont été supprimés
# fichier stat-<date> : contient nombre de menus/lignes conservés/supprimés
# fichier grub-mod : contient la 1ére ligne d'un menu qui a été modifié
# ou qui a été conservé pour une raison X
# les fichiers tmp[012]-<date> (coupures du fichier traité)
#########################################################################################
# quelques points d'historique
# V46++2020-04-11 ajout stat nb_lignes mod
# # remplacement [espacetab] par [[:blank:]] lignes 710-713-1409-1412-1424-1425
# # ok
# 2020-04-13 dans critere de suppression_2 ajout de la recherche de l'UUID par le /dev dans linux
# V46+ 2020-04-07 " LABEL" au lieu de "LABEL" dans grep et " TYPE" " UUID" " PARTUUID"
# V46 2018-11-23 utilisation de sed -r 's/.*\bLABEL="([^"]+)".*/\1/'
# au lieu de LABEL=${ligne#*LABEL=?} et LABEL=${LABEL%%\"*} #"
# fonctionne avec recup_fstab_V8 (idem ci-dessus)
# V44 2018-04-07 correction anomalie labels tronqués s'ils comportent des espaces
# concerne le $ récupération dev label uuid btype dans le fichier choisi vers ligne 1240
# fonctionne avec recup_fstab_V7 ( idem modification pour les labels tronqués )
# V43 2018-02-13 fonctionne avec V6
# V41 2017-03-23
# prend en compte le changement de label par un autre label
# ne fonctionnera que
# si on traite un grub modifié par modif_grub à partir de V7
# remarque on peut aussi repartir d'un grub tout neuf par update-grub
# les grub de tous les OS doivent être dans cet état
# on peut le voir si la ligne du menu entry comporte : après le label
# exemple menuentry 'U16.04-P10-64b : Ubuntu, avec Linux .......
# par contre la ligne suivante avec un nouveau label NOUVEAU
# menuentry 'M16.04-P12-64b,Ubuntu (sur /dev/sda12)'
# deviendrait
# menuentry 'NOUVEAU : M16.04-P12-64b,Ubuntu (sur /dev/sda12)'
# V40 qui fonctionne avec recup_fstab_V5
# les fichiers créés prennent un nom plus long (répertoire complet)
# les statistiques sont conservées dans ZZZnum/stat-<date>
# pour des raisons d'affichage , les _ des noms de fichiers créés sont remplacés par des -
# V39 répertoire des fichiers temporaires ZZZnum
# demande de suppression fichers
# V38 avec recup_fstab_V4
# ajout de l'option --sansfstab (permet de na pa lancer recup_fstab)
# ===> la création du fichier de concordance UUID-Part-UUIDBoot ne sera pas faite
# (hors ce fichier est nécessaire à modif_grub )
# et le fichier blkid ne sera pas mis à jour automatiquement
# V35 le programme ne traite plus que les lignes comprises entre
# ### BEGIN /etc/grub.d/10_linux ###
# et
# ### BEGIN /etc/grub.d/40_custom ###
# le fichier à traiter doit commencer par un #
# la ligne ### BEGIN /etc/grub.d/10_linux ### est obligatoire
# mais ne doit pas commencer le fichier
# si la ligne ### BEGIN /etc/grub.d/40_custom ### est absente
# le programme traitera le fichier de 10_linux jusqu'à la fin
# V34 suppression de certaines fonctions devenue inutiles
# réorganisation de certaines fonctions
# V33 ajout du sous programme recup_fstab_V2 ( étude système à boot séparé)
# V30 idem V29 sans les commentaires superflus
# si boot séparé on sort !!!!
# V29 2017-03-09
# correction due à l'utilisation de ${#uuid[*]} dans la construction concordance label-uuid
# remplacement de tous les while ${#menu[*]} par for ${!menu[@]}
# V28 2017-03-08
# présentation de concordances UUID-LABEL
# un ligne menuentry et submenu peut comporter des blank après }
# une ligne peut se terminer par } }
#V26 function sort_info_transforme donne des traces
# V25
# chaine_linux="linux.*\/vmlinu" pour prise en compte de "linux /@/boot/vmlinuz"
# V8 2017-02-14
# adjonction critere_suppression_2
# suppression des menus qui ont des UUID différents dans search --no-floppy et dans linux /boot/
# conservation des menus qui n'ont pas de lignes search --no-floppy
# conservation des menus qui n'ont pas de lignes linux /boot/vmlinu
# anomalie redoublement label , non modification de la ligne submenu
# V7 2017-02-13
# la ligne de submenu est recherché par submenu ' ou par submenu " au lieu de submenu 'Options .....
# l' UUID (et donc le label) est récupéré dans le bloc suivant de menuentry
# V6 2017-02-13
# on récupère l'UUID dans la ligne search --no-floppy --fs-uuid --set=root du bloc
# V5 2017-02-12
# seules les lignes commençant par menuentry et finisant par { seront traitées comme menuentry
# (le test se fait par ^[tab ]*menuentry.*{$)
# V4 2017-02-10
# il y aura suppression du menu si on trouve ....../dev/sd...../dev/sd...... AVANT la chaine --class ,
########################################################################################
function confirmation_sortie {
declare titre="Sortie de $0" # variables locales
declare ok="Confirmer la sortie"
declare texte="Pour Validez la sortie cliquer sur \"$ok\""
declare cancel="Abandonner la sortie"
if zenity --question --title "$titre" --text "$texte" \
--no-wrap --ok-label "$ok" --cancel-label "$cancel"
then
exit 63
fi
}
function suppression_fichiers_temporaires {
repertoire_a_vider="./$ZZZnum"
fich="/tmp/liste_fichier.txt" # contient la liste des fich. du rép. à supprimer
oklabel="Sortir si EXIT coché / Supprimer fichiers cochés sinon"
cancellabel="Re-cocher toutes les cases (sauf grub-OK)"
texte="
Des fichiers ont été créés lors de l'exécution du programme
$0
ci dessous ces fichiers encore existants dans le répertoire
$repertoire_a_vider
Pour supprimer un/des fichiers
1- Décochez la case EXIT
2- Cochez la case du/des fichier(s) que vous voulez supprimer
3- Cliquer sur $oklabel
==> ce menu se relancera en indiquant
les fichiers encore existants dans le répertoire $repertoire_a_vider
Pour SORTIR de ce menu une seule solution
Cochez la case EXIT puis cliquez sur \"$oklabel\"
pour Recocher la case de tous les fichiers (sauf grub-OK) cliquer sur la case
$cancellabel
"
while :
do
# listage des fichiers du répertoire
ls "$repertoire_a_vider" > "$fich" # ligne à supprimer en réel
liste_fichier="TRUE EXIT_(Sortir_du_menu)"
while read ligne
do # problème zenity ?
ligne=$(sed "s/ /*/g" <<< $ligne) # remplacer les espaces par *
case $ligne in
tmp[012][-_]20* | \
tmp[-_]u[-_]l* | \
tmp.txt | \
fich[-_]transforme-* | \
grub-mod* | \
stat-20* | \
DevSd[-_]UBoot* | \
grub-sup-20* | \
UBoot-UPart* )
liste_fichier="$liste_fichier TRUE $ligne" ;;
blkid-res.txt | \
grub-OK* )
liste_fichier="$liste_fichier FALSE $ligne" ;;
esac
done < "$fich"
#sélection des fichiers à supprimer
choix=`zenity --list \
--title="XXXXXXXXXXXXXXXXXXX : $0" \
--text="$texte" \
--checklist \
--cancel-label "$cancellabel" \
--ok-label "$oklabel" \
--height "750" \
--width "800" \
--column="CONS/SUP" --column="nom du(des) fichier(s) de $repertoire_a_vider" \
${liste_fichier} \
2>/dev/null ` # ne pas effacer cette ligne fin de choix
code=$?
echo "code de zenity $code"
if [[ $code == 0 ]] # code retour zenity (0=normal,sinon clic/x , Esc , )
then
[[ -n `echo $choix|grep "EXIT"` ]] && exit 0
if [[ -z $choix ]] # $choix est vide
then
echo "Aucun choix effectué"
continue # on recommence
else
echo "le choix est :"
echo "$choix"
IFS="|"
list=($choix)
echo "le 1er est ${list[0]}"
echo "le 2ème est ${list[1]}"
echo ${list[@]}
IFS="$OLDIFS"
if zenity --question --title "SUPPRESSION" \
--text "Suppression de ${#list[@]} fichiers" \
--no-wrap --ok-label "Confirmer Suppression" \
--cancel-label "Abandonner la Suppression"
then
for i in ${list[@]}
do
i=$(sed "s/*/ /g" <<< $i) #remettre espace à la place des *
echo "je supprime $repertoire_a_vider/$i"
rm "$repertoire_a_vider/$i"
done
fi
continue # on recommence
fi
else
[[ $code == 1 ]] && continue # on a cliqué sur Re-cocher
fi
confirmation_sortie
done
}
function ne_commence_pas_par_begin {
# le fichier à traiter ne doit pas commencer par ### BEGIN /etc/grub.d/10_linux ###
read ligne < "$fich_source"
if [[ "$ligne" =~ ^"$deb" ]]
then
echo ; echo
echo "désolé"
echo "le fichier grub à traiter ( $fich_source )"
echo "n'a pas le droit de commencer par la ligne"
echo "$deb"
echo "rappel :"
echo " 1- cette ligne"
echo " $deb"
echo " DOIT apparaître plus loin dans le fichier"
echo " même pour un fichier grub d'essai"
echo
echo " 2- le fichier à traiter DOIT commencer par une ligne de commentaire"
echo " (car cette première ligne sera modifiée)"
echo
echo " 3- en réel le fichier grub commence par #"
exit 1 # au lieu de return 1
fi
}
function trier_fichier {
echo ; echo
echo "fichier grub choisi : $fich_source"
deb="### BEGIN /etc/grub.d/10_linux ###"
fin="### BEGIN /etc/grub.d/40_custom ###"
ne_commence_pas_par_begin
# création de 3 fichiers tmp0-<date>.txt tmp1-<date>.txt tmp3-<date>.txt
[[ -e "$fich_source_0" ]] && rm "$fich_source_0" # inutile mais évite message d'erreur rm
[[ -e "$fich_source_1" ]] && rm "$fich_source_1" # inutile mais évite message d'erreur rm
[[ -e "$fich_source_2" ]] && rm "$fich_source_2" # inutile mais évite message d'erreur rm
fich="$fich_source_0"
presence_10_linux=1
IFS="~"
while read ligne
do
case "$ligne" in
$deb ) fich="$fich_source_1" ; presence_10_linux=0 ;;
$fin ) fich="$fich_source_2" ;;
esac
echo "$ligne" >> $fich
done < "$fich_source"
IFS="$OLDIFS"
# après lecture du fichier on a du renconter le ligne 10_linux sinon
if [[ $presence_10_linux -eq 1 ]]
then
echo "la présence de la ligne $deb est obligatoire"
echo "le traitement ne commence qu'à partir de cette ligne"
echo "ajouter cette ligne au fichier"
exit 0
fi
}
function verifier_presence_dev { # dans le cas d'utilisation d'un blkid personnel
#chaque dev de la machine doit être déclaré dans le fichier manuel !!!
echo
# mettre les dev de "sudo blkid" dans un tableau
dev1=(`awk -F" " '{printf("%s ",$1)}' "$blkid"`)
# mettre les dev du fichier choisi dans un tableau
dev2=(`awk -F" " '{printf("%s ",$1)}' "$blkid_choisi"`)
manque=""
for d1 in ${dev1[@]} # /dev/sdxy: /dev/sdzt: de blkid
do
res=`grep $d1 <<< ${dev2[@]}`
[[ -z $res ]] && manque="$manque $d1" # si non trouvé , ajout
done
if [[ -n $manque ]]
then
echo "dans le fichier $blkid_choisi il manque"
echo ; echo $manque ; echo
echo "tous les dev présents sur la machine doivent être déclarés dans ce fichier"
echo "veuillez éditer ce fichier"
echo "format habituel dev/sdxx: LABEL=\"xxxx\" UUID=\"xxxx\""
echo " un caractère espace est requis devant LABEL et UUID"
echo " UUID est obligatoire"
echo " la présence de LABEL n'est pas obligatoire"
exit 0
fi
}
function modif_ligne1_grub { # récupère la première ligne et modifie en y mettant la date
res=`echo "$1" | grep "^ * *#"`
if [[ -n $res ]] # la ligne est bien un commentaire (commence par #)
then
trans="#### $num : $fich_source modifié par $0 ####"
echo $trans > "$fich_sauv"
((nb_lignes_cons++))
((nb_lignes_hors_menu++))
sort_info_transforme "$1" "première ligne modifiée en" "$trans"
else
echo "la première ligne du fichier est "
echo $1
echo
echo "mais il faut que la première ligne du fichier"
echo "$fich_source"
echo "commence par un #"
echo "ajouter cette ligne de commentaire au début de ce fichier"
echo "arrêt du programme"
exit 0
fi #[[ -n $res ]]
}
function OK {
rep=""
while [[ $rep != [oOyYnN] ]]
do
titre="programme $0"
texte="cette partie de programme supprime des lignes supposées inutiles de grub
- paragraphes contenant ......$rech_dev.....$rech_dev........... AVANT la chaine $rech_class
- menuentry n'ayant pas des UUID égaux dans la ligne search et la ligne linux
(à partir de V34 les menuentry sur boot séparé sont conservés)
- le programme demande le nom du fichier à traiter ..
==> en réel ce devrait être <partition>/boot/gub/grub.cfg
- le programme crée un fichier grub-OK-date qui pourra être utilisé pour remplacer le fichier grub
- le programme utilise aussi le label des partitions ou d'un fichier de référence
pour informer plus précisement la ligne menuentry de grub,
on peut utiliser un fichier de référence uuid label (au format blkid)
- remarque : pour des essais , on peut traiter n'importe quel fichier ayant un format grub
si le fichier à traiter n'est pas au format grub , il ne fonctionnera pas correctement
et en réel il serait préférable de lancer ce programme après avoir lancé un update-grub
trois fichiers sont créés :
grub-OK -<aaaa:mm:dd-hh:mm:ss>.txt ( le grub reformaté )
grub-sup-<aaaa:mm:dd-hh:mm:ss>.txt ( les menuentry qui ont été supprimés )
grub-mod-<aaaa:mm:dd-hh:mm:ss>.txt ( les lignes modifiées )
vous pourrez analyser ces fichiers pour voir ce qui s'est passé
avant de remplacer le fichier traité (surtout si c'est grub.cfg)
(en fin de traitement répondez alors non à la demande de remplacement
et faites le remplacement manuellement)
lors du traitement ..... ( c'est uniquement une info visuelle )
les x qui défilent indiquent des lignes de menu qui seront supprimées
les c qui défilent indiquent les lignes de menu qui seront conservées
les . qui défilent indiquent les autres lignes (qui seront conservées)
un S indique un début de submenu
un M indique un début de menuentry
un m indique la suite de menuentry
tapez O puis valider pour continuer
tapez A puis valider pour arrêter
O pour continuer / A pour arrêter le programme
"
rep=`zenity --entry --title "$titre" --text "$texte" --width "800"`
case $rep in
[oOyY] ) : ;;
[aA] ) exit 1 ;;
* ) echo "utilisez seulement oOyYaA S.V.P." ;;
esac
done
}
function choix_fichier_blkid { # retourne 0 si fichier blkid choisi
fichier_source=""
titre="$0 Sélectionnez le fichier contenant UUID et LABEL des partitions"
fichier_source=`zenity --file-selection --title="$titre"`
case $? in #$? est le code de retour de zenity
0) blkid_choisi="$fichier_source" ;;
1) echo "Aucun fichier UUID-LABEL sélectionné." ; exit 1 ;;
-1) echo "Une erreur inattendue est survenue." ; exit 1 ;;
*) echo "erreur non reconnue" ; exit 1 ;;
esac
}
function critere_suppression_2 { # se fait après une initialisation de menu[0 ...n]
##### attention les codes de retour ont changé
# 0 si ligne search et ligne linux et uuid égaux (menu conservé + label dans menu[0])
# 1 si pas de ligne search ou linux (menu conservé intégralement)
# ligne search et linux trouvées
# 3 aucun UUID trouvé dans fichier UUID-LABEL
# 2 si uuid différents (menu supprimé à revoir?)
uuid_search="x"
uuid_linux="y"
ligne_search=""
ligne_linux=""
# recherche dans le tableau menu[1..n] de la ligne search
#TEST
for i in ${!menu[@]} # pour tous les indices 0..n
do
[[ $i = 0 ]] && continue # sauf dans menu[0]
res=`grep "$chaine_search" <<< "${menu[i]}"` # dans menu[1..n]
if [[ -n $res ]]
then
ligne_search="${menu[i]}"
break # 1er menu[n] trouvé est le bon
fi
done
if [[ -z "$ligne_search" ]]
then
return 1 # pas de chaine search => on conservera le menu intégralement
fi
# recherche dans le tableau menu[] de la ligne linux
for i in ${!menu[@]} # pour tous les indices 0..n
do
[[ $i = 0 ]] && continue # sauf dans menu[0]
tmp=`sed 's/[[:blank:]]//g' <<< "${menu[i]}"` #suppression des blank de menu
res=`grep "$chaine_linux" <<< "${menu[i]}"` # dans menu[1..n]
if [[ -n $res ]]
then
ligne_linux="${menu[i]}"
break # 1er menu[n] trouvé est le bon
fi
done
if [[ -z "$ligne_linux" ]]
then
return 1 # pas de chaine linux => menu conservé sans modif
fi
#uuid ligne search présent dans fichier de réf uuid-label ?
# si trouvé positionne uuid_search
n=-1
while [[ $n -lt $maxuuid ]]
do
((n++)) # recherche de uuid[0..n]
if [[ -n ${uuid[$n]} ]] # précaution supplémentaire uuid non vide
then
res=`grep ${uuid[$n]} <<< "$ligne_search"` # y-a-t-il l'UUID
if [[ -n $res ]]
then
uuid_search=${uuid[$n]}
break # le premier uuid trouvé dans blkid sera le bon
fi
fi
done
# uuid ligne linux présent dans fichier de réf uuid-label ?
# si trouvé positionne uuid_linux
n=-1
while [[ $n -lt $maxuuid ]]
do
((n++)) # recherche de uuid[0..n]
if [[ -n ${uuid[$n]} ]] # précaution supplémentaire uuid non vide
then
res=`grep ${uuid[$n]} <<< "$ligne_linux"` # y-a-t-il l'UUID
if [[ -n $res ]]
then
uuid_linux=${uuid[$n]}
break # le premier uuid trouvé dans blkid sera le bon
fi
fi
done
#echo;echo $LINENO $ligne_linux $uuid_linux;sleep 2
# V46 +++ on peut trouvé root=/dev/sdxy au lieu de root=UUID==
# if uuid_linux inchangé (y) , recherche uuid par le dev , et on recherche l'uuid du
if [[ $uuid_linux = "y" ]]
then
n=-1
while [[ $n -lt $maxuuid ]]
do
((n++)) # recherche de uuid[0..n]
if [[ -n ${dev[$n]} ]] # précaution supplémentaire dev non vide
then
res=`grep "${dev[$n]} " <<< "$ligne_linux "` # /dev dans la ligne? espace pour différencier "/dev/sda1 " <<< "dev/sda10 "
#echo;echo $LINENO $res
#echo $LINENO ${dev[$n]}
#echo $LINENO $ligne_linux
if [[ -n $res ]]
then
#echo $LINENO $ligne_linux $uuid_linux;sleep 2
uuid_linux=${uuid[$n]} # car dev et uuid ont le même indice !!!!!
break # le premier dev trouvé dans blkid sera le bon
fi
fi
done
fi
#echo;echo $LINENO $ligne_linux $uuid_linux;sleep 2
# analyse des résultats
if [[ ${uuid_search}${uuid_linux} = "xy" ]]
then
return 3 # aucun des uuid n'a été trouvé dans blkid ( peuvent être égaux ou non )
fi
####################################################################################
# on peut avoir uuid_search uuid_linux
# x 1ea0.... : n'existe pas , existe : code retour 2
# a04f... y : existe , n'existe pas : code retour 2
# bcde... fghi.... : uuids existants et différents: code retour 2
# 1234... 1234.... : uuids existants et égaux : code retour 0
#####################################################################################
# si $uuid_search-$uuid_linux est dans UBoot on renvoie 4
# ce menu correspond à une partition avec boot séparée
for i in ${!UBoot[@]} # pour tous les indices 0..n
do
[[ $uuid_search-$uuid_linux = ${UBoot[$i]} ]] && return 4
done
if [[ "$uuid_search" != "$uuid_linux" ]]
then
return 2 # uuid différents on supprimera ce menu
else
return 0 # uuid egaux on conservera ce menu après modif de menu[0]
fi
} # fin function critere_suppression_2
function ajout_label_menuentry { # ajoute un label à menu[0] (search ou linux)
rech_uuid_label_menuentry "$1" # retour 0 si label trouvé , pas zéro sinon
code=$?
if [[ $code -eq 0 ]]
then # on a un label
tmp=${menu[0]}
# menu[0]=`sed "s/menuentry '/menuentry '$label_trouve : /" <<< ${menu[0]}`
# menu[0]=`sed "s/menuentry \"/menuentry \"$label_trouve : /" <<< ${menu[0]}`
# menu[0]=`sed "s/${label_trouve} *:* *${label_trouve}/${label_trouve}/" <<<${menu[0]}`
# 1 remplacement de l'ancien par le nouveau , (s'il n'y a pas d'ancien ,rien n'est changé)
menu[0]=`sed "s/menuentry '.* : /menuentry '$label_trouve : /" <<< ${menu[0]}`
menu[0]=`sed "s/menuentry \" .*: /menuentry \"$label_trouve : /" <<< ${menu[0]}`
# 2 ajout du nouveau en tête
menu[0]=`sed "s/menuentry '/menuentry '$label_trouve : /" <<< ${menu[0]}`
menu[0]=`sed "s/menuentry \"/menuentry \"$label_trouve : /" <<< ${menu[0]}`
# 3 suppression des doublons
menu[0]=`sed "s/${label_trouve} *:* *${label_trouve}/${label_trouve}/" <<<${menu[0]}`
if [[ $tmp != ${menu[0]} ]]
then
sort_info_transforme "$tmp" " LIGNE transformée en" "${menu[0]}"
((nb_lignes_mod++)) # ajout V46++
fi #[[ $tmp != ${menu[0]} ]]
fi # [[ $code -eq 0 ]]
}
function memorise_menuentry { # mémorise menuentry de submenu pour écriture ultérieure
for p in ${!menu[@]} # pour tous les indices de menu[]
do
((i_s++))
ligne_sousmenu[i_s]=${menu[$p]} # mémorise menu[0 ..n]
((nb_lignes_menu_cons++)) # stat
done
}
function ecrire_lignes_memorisees { # écrit les lignes dans sauv
for p in ${!ligne_sousmenu[@]} # pour tous les indices de ligne_sousmenu[]
do
echo "${ligne_sousmenu[$p]}" >> "$fich_sauv" # écriture l_s[0..n]
((nb_lignes_cons++)) # stat
done
}
function traite_ligne_submenu { # reçoit $1 (ligne submenu '.......{
fin_submenu=1 # sera mise à 0 si un menuentry se termine par } }
submenu="$1" #mise en mémoire de cette ligne
# j'utilise la mémorisation label_submenu du label d'un menuentry précédent
if [[ -n $label_submenu ]]
then
# ajout du label et suppression double label
submenu=`sed "s/submenu '/submenu '${label_submenu} : /" <<< $submenu`
submenu=`sed "s/submenu \"/submenu \"${label_submenu} : /" <<< $submenu`
submenu=`sed "s/${label_submenu} *:* *${label_submenu}/${label_submenu}/" <<<$submenu`
fi
i_s=0
unset ligne_sousmenu
ligne_sousmenu[0]="$submenu" # mémorisation pour sortie finale
((nb_lignes_hors_menu++)) # ligne considérée comme hors menu
# lire les lignes qui suivent submenu jusquà trouver ligne ......} hors menuentry)
while read ligne
do
((nb_lignes_lues++))
# si on trouve .... } hors menuentry on est au bout du submenu
# il faut sauvegarder la ligne submenu , les lignes intermédiaires et menuentry
# je ne traite pas du cas où on trouverait une ligne menuentry terminée par } }
# V28 et suivante ce cas est traité
# une ligne menuentry terminée par } } provoque la fin du submenu ($fin_submenu 0)
# on sort de la boucle si on trouve } en fin de ligne hors menuentry
tmp=`sed 's/[[:blank:]]//g' <<<"$ligne"` # supprime tous les blancs de la ligne
if [[ "$tmp" =~ }$ || "$fin_submenu" = 0 ]] ### on est en fin de submenu ###
# pas tout à fait exact
# si on peut avoir { ...... } hors menuentry
then
((i_s++))
ligne_sousmenu[i_s]="$ligne" # mémoriser cette ligne
((nb_lignes_hors_menu++)) # stat
echo -e ".\c"
ecrire_lignes_memorisees # écriture de ces lignes de submenu
label_submenu=""
return # fin de traitement de submenu
fi # [[ "$tmp" =~ }$ ]]
# V28 élargissement aux blancs de grep après {
res=`echo "$ligne" | grep "^[[:blank:]]*menuentry.*{[[:blank:]]*$"`
mem=`echo "$ligne" | grep "^[[:blank:]]*menuentry ['\"]Memory test.*{[[:blank:]]*$"`
#res=`echo "$ligne" | grep "^[ ]*menuentry.*{[ ]*$"`
#mem=`echo "$ligne" | grep "^[ ]*menuentry ['\"]Memory test.*{[ ]*$"`
if [[ -n $mem ]]
then
res="" # si on trouve la chaine Memory pas intéressant on force res à vide
fi
if [[ -z $res ]]
then # ni menuentry ..{ ni memory ...{
((i_s++)) #
ligne_sousmenu[i_s]="$ligne" # mise en mémoire pour écriture ultérieure
((nb_lignes_hors_menu++)) # stat
echo -e ".\c"
else
lire_menuentry # menu[0..n] et ((nb_lignes_lues++))
trt_menu2 "${menu[0]}" # 1 si contient dev dev
code_dev_dev=$?
if [[ $code_dev_dev -eq 1 ]] # 1 la ligne contient /dev /dev
then
sort_menu_1 " " "menu supprimé : trop de /dev/sd" # suppression de ce menu
((nb_menu_sup++)) # stat
else # pas 1 : ne contient pas dev dev
critere_suppression_2
code_crit2=$? # 0 1 2 3
case $code_crit2 in
0) # les uuid sont égaux modifier menu[0]
ajout_label_menuentry "$chaine_search"
memorise_menuentry # mettre en mémoire ces lignes de menuentry
((nb_menu_cons++)) # stat non prévu dans memorise_menuentry
;;
1) # pas de search ni de linux on garde sans modif
memorise_menuentry # mettre en mémoire ces lignes de menu
sort_info_transforme "${menu[0]}" "menu dans submenu conservé (pas de ligne search ou linux)"
((nb_menu_cons++)) # stat non prévu dans memorise_menuentry
;;
2) # uuid différents on supprime ce menu
sort_menu_1 " " "menu supprimé : uuid différents"
((nb_menu_sup++)) # stat non prévu
;;
3) # uuid non trouvé (search et linux existent)
memorise_menuentry # mettre en mémoire ces lignes de menu
sort_info_transforme "${menu[0]}" "menu dans submenu conservé : uuid (search ou linux) non trouvé"
((nb_menu_cons++)) # stat non prévu
((nb_menu_sans_uuid++))
;;
4) # uuid != mais boot séparé
# revoir pour le label
ajout_label_menuentry "$chaine_linux"
memorise_menuentry # mettre en mémoire ces lignes de menuentry
((nb_menu_cons++)) # stat non prévu dans memorise_menuentry
((nb_menu_boot_cons++))
;;
esac
fi # [[ $code_dev_dev -eq 1 ]]
fi # [[ -z $res ]]
done
# si on arrive ici il y a erreur de traitement quelque part
echo
echo " ligne bach $LINENO"
echo " erreur de format ? dans le fichier $fich_source !!!!!!!!!!"
echo " dernière ligne de menu lue :"
echo
echo ${menu[0]}
echo
echo " dernière ligne lue : $nb_lignes_lues"
echo " $ligne"
sleep 100
exit 0
}
function rech_uuid_label_ligne { # recherche uuid et label de $1 dans uuid[0..n]
# renvoie 0 uuid trouvé et label trouvé uuid_trouve=xxx label_trouve="yyy"
# renvoie 1 uuid trouvé et label vide uuid_trouve=xxx label_trouve=""
# renvoie 2 uuid non trouvé uuid_trouve="" label_trouve=""
uuid_trouve=""
label_trouve=""
n=-1
while [[ $n -lt $maxuuid ]]
do
((n++)) # uuid suivant
if [[ -n ${uuid[$n]} ]] # précaution supplémentaire uuid non vide
then
res=`grep ${uuid[$n]} <<< $1` # $1 est une ligne de menu
if [[ -n $res ]]
then
uuid_trouve=${uuid[$n]}
if [[ -n ${label[$n]} ]]
then
label_trouve=${label[$n]} # si label non vide positionne label_trouve
return 0 # uuid trouvé / label non vide trouvé
else
return 1 # uuid trouvé / label ""
fi
fi
fi
done
return 2 # uuid non trouvé
}
function rech_uuid_label_menuentry { # recherche uuid et label dans la ligne $1 de menu[1 ..n]
for p in ${!menu[@]} # pour tous les indices du tableau 0..n
do
[[ $p = 0 ]] && continue # mais pas dans menu[0]
res=`echo ${menu[$p]} | grep "$1"`
if [[ -n $res ]]
then
rech_uuid_label_ligne ${menu[$p]} # donne uuid_trouve / label_trouve
return $? # 0 uuid égaux
# 1 uuid trouvé , label vide
# 2 pas d'uuid dans search
fi
done
return 3 # pas de search trouvé , (donc pas d'uuid , et donc pas de label) !!!
}
function transforme_ligne_menuentry { # modifie la première ligne d'un menuentry conservé
# recherche l'UUID dans la ligne search --no-floppy --fs-uuid --set=root
# si trouvé , on récupère le label
# si label vide on ne fait rien
# sinon on rajoute avec : en tête après menuentry ' ou menuentry "
#
label_trouve=""
uuid_trouve=""
tmp=${menu[0]} # servira de test pour sortie si modifié
rech_uuid_label_menuentry "$1" # positionne le label à la bonne valeur
code=$? # retour de la fonction
case $code in
0) # UUID trouvé : $uuid_trouve LABEL trouvé : $label_trouve
if [[ $label_submenu = "" ]] # servira dans traitement d'un submenu éventuel
then # on memorise le premier label menuentry trouvé
label_submenu="$label_trouve"
fi
# menu[0]=`sed "s/menuentry '/menuentry '$label_trouve : /" <<< ${menu[0]}`
# menu[0]=`sed "s/menuentry \"/menuentry \"$label_trouve : /" <<< ${menu[0]}`
#suppression double labels dans cette ligne
# menu[0]=`sed "s/${label_trouve} *:* *${label_trouve}/${label_trouve}/" <<<${menu[0]}`
# 1 remplacement de l'ancien par le nouveau , (s'il n'y a pas d'ancien ,rien n'est changé)
# 2 ajout du nouveau
# 3 suppression des doublons
# 1 remplacement de l'ancien par le nouveau , (s'il n'y a pas d'ancien ,rien n'est changé)
menu[0]=`sed "s/menuentry '.* : /menuentry '$label_trouve : /" <<< ${menu[0]}`
menu[0]=`sed "s/menuentry \" .*: /menuentry \"$label_trouve : /" <<< ${menu[0]}`
# 2 ajout du nouveau en tête
menu[0]=`sed "s/menuentry '/menuentry '$label_trouve : /" <<< ${menu[0]}`
menu[0]=`sed "s/menuentry \"/menuentry \"$label_trouve : /" <<< ${menu[0]}`
# 3 suppression des doublons
menu[0]=`sed "s/${label_trouve} *:* *${label_trouve}/${label_trouve}/" <<<${menu[0]}`
if [[ $tmp != ${menu[0]} ]]
then #TEST
sort_info_transforme "$tmp" " LIGNE transformée en" "${menu[0]}"
#echo "$LINENO ${menu[0]} avant $nb_lignes_mod"
(( nb_lignes_mod++ )) # ajout V46++
#echo "après $nb_lignes_mod"
fi
;;
1) # LABEL vide #TEST
sort_info_transforme "$tmp" "pas de label pour $uuid_trouve dans $blkid_choisi"
;;
2) #LABEL vide uuid non trouvé #TEST
sort_info_transforme "$tmp" "uuid de ligne search non trouvé dans $blkid_choisi"
;;
3) # pas de ligne search trouvée dans menuentry v
sort_info_transforme "$tmp" "ligne search non trouvée"
;;
*) # ???? #TEST
sort_info_transforme "$tmp" "code inconnu : $code"
;;
esac
return $code
}
function lire_menuentry { # met dans tableau menu[n] jusqu'à trouvé } seul sur la ligne
unset menu
i=0
menu[0]="$ligne" # menu[0] est la première ligne
echo -e "M\c" # trace début de menuentry
while read ligne # ligne suivante
do
((i++))
((nb_lignes_lues++))
menu[$i]="$ligne" # mémorisée dans menu [1 .. n]
echo -e "m\c" # trace écran
tmp=`sed 's/[[:blank:]]//g' <<<"$ligne"` # suppression des blancs pour test
if [[ "$tmp" =~ }}$ ]]
then
fin_submenu=0 # termine par } } fin de submenu !!!
fi
if [[ "$tmp" =~ }$ ]] # la ligne se termine par } ?
then
return # oui fin de menuentry
fi
# et si pas de ... } on ira jusqu'en fin de fichier !!!!
# c'est un critère de format de grub
done
}
function sort_menu_0 { # écrit menu[0..n] dans le fichier de sauvegarde
for p in ${!menu[@]} # pour tous les indices
do
echo "${menu[$p]}" >> "$fich_sauv" # écriture menu[0..n]
((nb_lignes_cons++)) # stat
((nb_lignes_menu_cons++)) # stat
echo -e "c\c" # suivi écran
done
}
function sort_menu_1 { # écrit menu[0..n] dans le fichier suppression
#écriture des paramètres reçus dans fich_sup
echo "#########################" >> $fich_sup
for arg in "$@" # prends $1 $2 ... $n
do
echo $arg >> $fich_sup
#echo >> $fich_sup
done
# écriture du menu dans fichier sup
for p in ${!menu[@]} # pour tous les indices
do
echo "${menu[$p]}" >> "$fich_sup" # écriture menu[0..n]
((nb_lignes_sup++)) # stat
echo -e "x\c" # suivi écran
done
}
function sort_info_transforme { # écrit les paramètres reçus fich_transforme
echo "#########################" >> $fich_transforme
for arg in "$@" # ( $1 $2 ... $n )
do
echo $arg >> $fich_transforme
#echo >> $fich_transforme
done
}
function trt_menu2 { # analyse le paramètre $1
# renvoie 1 si $1 contient plus d'une fois /dev/sd avant --class (suppresion)
# renvoie 0 sinon
IFS="$OLDIFS" # il faut l'espace comme délimiteur
tableau=($1) # mise en tableau de la ligne
IFS="~" # peut-être utile pour la suite ?
nbdevsd=0 # nombre de fois que l'on trouve /dev/sd (avant --class)
for n in ${!tableau[@]} # de 0 1 2 .... x
do
r_class=`echo ${tableau[$n]} | grep "$rech_class"` # test présence --class
if [[ -n $r_class ]] # --class ou pas ?
then
break # --class est trouvé, sort de la boucle for
else
r_dev=`echo ${tableau[$n]} | grep "$rech_dev"` # test présence /dev/sd
if [[ -n $r_dev ]]
then
((nbdevsd++)) # incrémente si on a /dev/sd
if [[ $nbdevsd -gt 1 ]] # si plus d une fois /dev/sd
then
return 1 # on sort en renvoyant 1
fi #[[ $nbdevsd -gt 1 ]]
fi #[[ -n $r_dev ]]
fi #[[ -n $r_class ]]
done
if [[ $nbdevsd -gt 1 ]] # test nombre
then
return 1 # 1 si plus d'une fois /dev/sd
else
return 0 # 0 sinon
fi
}
#trt=0;((trt++));echo "début de traitement $trt - $LINENO";read g
# début du programme ##################################################################################
######### variables ###################################
OLDIFS="$IFS" # sauvegarde IFS
rech_class="\-\-class" # jusqu'à trouver la chaine --class dans menuentry
rech_dev="\/dev\/sd" # la présence de la chaine /dev/sd dans menuentry
# ne pas modifier le nom des fichiers suivants
blkid="blkid-res.txt" # (fichier contenant le résultat de sudo blkid)
fich_fstab_conc="UBoot-UPart.txt" # créé par recup-fstab contient les uuid ayant boot séparé
blkid_choisi="" # fichier personnel choisi contenant dev-label-uuid
chaine_search="search \-\-no\-floppy \-\-fs\-uuid \-\-set=root"
# (un tiret doit être protégé par \ pour une recherche dans grep)
chaine_linux="linux.*\/vmlinu" # + général "linux......./vmlinu"
label_submenu="" # label valide du menuentry précédent
ZZZnum="ZZZnum" # le répertoire qui contiendra les fichiers temporaires xxxx-$num
prg="$nom_dir/recup_fstab_V8" # création de $fich_fstab_conc (UBoot_UPart.txt)
#########################################################
num=`date +%Y:%m:%d`-`date +%H:%M:%S`
# ces 3 variables seront re-précisées en utilisant le nom complet du fichier grub traité
fich_sauv=""
fich_sup=""
fich_transforme=""
fich_source_0="$ZZZnum/tmp0-$num.txt" # lignes de 1 à 10_linux[
fich_source_1="$ZZZnum/tmp1-$num.txt" # lignes de [10_linux à 40_custom[
fich_source_2="$ZZZnum/tmp2-$num.txt" # lignes de [40_custom à la fin]
##### pour les stat #####################################
fich_stat="$ZZZnum/stat-$num.txt"
nb_menu_cons=0
nb_menu_boot_cons=0
nb_menu_sup=0
nb_menu_sans_uuid=0
nb_lignes_sup=0
nb_lignes_cons=0
nb_lignes_lues=0
nb_lignes_hors_menu=0
nb_lignes_menus_cons=0
nb_lignes_mod=0 # ajout V46++
#########################################################
! [[ -e "$ZZZnum" ]] && mkdir "$ZZZnum" # pourrait être mis plus loin
#((trt++));echo "début de traitement $trt - $LINENO";read g
#si le programme $prg (recup_fstab_Vx) n'existe pas on sort
# voir pour utiliser getopts
# deux façons de lancer ce programme
# - en terminal avec ou sans l'option --sansfstab
# - clic sur le fichier (sans l'option --sansfstab)
case "$1" in
--sansfstab )
echo "
Rappel :
un fichier à jour au format blkid
(dev - uuid - label éventuel)
est nécessaire au bon déroulement du programme
s'il y a des OS avec boot séparés
un fichier
$fich_fstab_conc à jour
est nécessaire (il est créé par recup_fstab)
(ce fichier donne l'uuid de la partition de boot
associé à l'uuid de la partition système)
en cas de doute utilisez
$0 sans le paramètre --sansfstab
pour re-créer correctement ce fichier
Taper sur Entrée pour continuer Ctrl C pour arrêter"
#touch $fich_fstab_conc # création artificielle du fichier
read g
code=0 ;;
* )
! [[ -e "$prg" ]] && echo "fichier $prg de récup. (fstab et blkid) manquant" && read g && exit 0
echo "$0 lance le programme $prg"
$prg "$ZZZnum"
code=$?
;;
esac
echo "le code de retour est $code"
((trt++));echo "début de traitement $trt $LINENO"
if [[ $code -ne 0 ]]
then
echo " il y a eu un problème de traitement du programme $prg"
echo " si l'arrêt n'est pas volontaire"
echo " vérifier que le répertoire /mnt/jpb ne comporte pas des résidus de fichiers"
echo " éventuellement faire le ménage dans ce répertoire"
read g
exit 0
fi
echo
echo "suite du programme $0"
echo ; echo
# pour les fichiers temporaires -$num
if ! [[ -e $fich_fstab_conc ]] # UBoot_UPart a normalement été créé par recup_fstab
then
echo "le fichier $fich_fstab_conc est introuvable"
echo "il faut d'abord exécuter $prg"
echo "ou mettre à disposition manuellement un fichier $fich_fstab_conc"
echo ; echo ; read g
exit 0
else
echo " vérification des uuid correspondants à des systèmes sur boot séparés"
echo " couples uuid-boot - uuid-systeme des menuentry en boot séparé"
echo
echo "###### contenu du fichier $fich_fstab_conc #############################"
cat $fich_fstab_conc
echo "#######################################################################"
echo
echo " vérifier visuellement le contenu des lignes comprises entre les ###"
echo " il existe deux lignes par couple (ou rien)"
echo " une ligne uuid1-uuid2"
echo " une ligne uuid2-uuid1"
echo
echo " tapez sur entrée pour continuer"
read g
fi
# lecture et mise en mémoire des infos donnée par le fichier $fich_fstab_conc ("UBoot_UPart.txt")
#################################################################################################
max_boot=-1
while read l_boot
do
[[ -z $l_boot ]] && echo "ligne vide je passe" && continue # si ligne vide ou commentée
[[ $l_boot =~ ^[[:blank:]]*# ]] && echo "ligne commentée $l_boot je passe" && continue
((max_boot++))
echo $l_boot
UBoot[$max_boot]=$l_boot # format uuid1-uuid2 à la suite
done < $fich_fstab_conc
#################################################################################################
OK # présentation du programme
code=1
while [[ $code = 1 ]]
do
rep=""
texte_supplementaire=""
if ! [[ -e "$blkid" ]]
then
texte_supplementaire="=====> !!!!! Attention ce fichier $blkid n'est pas présent !!!!!!"
fi
while [[ $rep != [oOyYaAcC] ]]
do
titre=" Utilisation des UUID et LABEL des partitions des disques"
texte=" Choix du fichier de références LABEL et UUID
répondez par
(oOyY) si vous voulez ré-utiliser le fichier $blkid
ce fichier a été créé précédemment par $prg
(contient les labels utilisés pour mettre à jour le grub
seront alors ceux déclarés sur la partition)
$texte_supplementaire
(cC) permet de choisir un fichier de référence UUID LABEL
(les labels utilisés pour mettre à jour le grub
seront alors ceux déclarés dans ce fichier de référence)
!!!!! mais toutes les partitions devront être déclarées
le champ /dev/sdxx en premier
le champ LABEL="xxxxxx" non obligatoire (mais alors
le menu de GRUB ne sera pas modifié pour ce dev)
le champ UUID="xxxxxx" (OBLIGATOIRE pour un traitement correct)
le champ type TYPE="xxxxx" est conseillé
une ligne sera donc de la forme
/dev/sdxx LABEL=\"un label correct\" UUID=\"un uuid correct\" TYPE=\"le type correspondant\"
ce choix peut servir si vous ne voulez pas labelliser les
partitions mais mettre quand même un label dans grub
ou bien pour effectuer des essais
(ce choix un peu tordu est un peu difficile à comprendre ?)
!!!! en cas de doute utilisez le choix oOyY puis Valider
O pour réutilisation du fichier $blkid
C pour choisir un fichier de référence UUID LABEL personnel
A Arrêter"
rep=`zenity --entry --title "$titre" --text "$texte" --width "800"`
case $rep in
[oOyY] ) blkid_choisi="$blkid"; echo "utilisation du fichier créé précédemment)" ;;
[aA] ) echo "arrêt du programme" ; exit 0 ;;
[cC] ) echo "choix du fichier des uuid" ; choix_fichier_blkid ;;
* ) echo "utilisez seulement oO yY aA cC S.V.P." ;;
esac
done
# si le fichier de concordance n'existe pas sortie
if ! [[ -e "$blkid_choisi" ]]
then
echo ; echo
echo " $0 n'a pas trouvé le fichier"
echo " $blkid_choisi"
echo " que vous avez choisi comme référence UUID-LABEL"
echo " Modifier votre choix de fichier"
echo " ou bien mettez à disposition ce fichier pour continuer"
echo ; echo ; sleep 2
else
code=0
fi
done # sors de la boucle uniquement si code=0
# récupératon dev label UUID dans des tableaux
unset dev
unset uuid
unset label
unset bdev # à partir de V31 pour boot séparé
unset btype # le type de la partition
unset bmont # point de montage à cause du boot séparé
############## récupération dev label uuid btype dans le fichier choisi ###################
maxuuid=-1
while read ligne
do
[[ -z $ligne ]] && echo "ligne vide je passe" && continue # correction ligne vide
[[ "$ligne" =~ ^[[:blank:]]*#.*$ ]] && continue # autorise ligne commentée
ligne=${ligne##[[:blank:]]} # suppression des [[:blank:]] au début
echo "=>$ligne<= =>$(grep "^\/dev" <<< "$ligne")<="
res=$(grep "^\/dev" <<< "$ligne")
if [[ -z $res ]]
then
zenity --info --title="$blkid_choisi" --text="ligne $maxuuid la ligne \n $ligne \n ne commence pas par \/ \n c'est interdit" --width=500 && /
exit 0 # arrêt si une ligne ne commence pas par /
fi
((maxuuid++))
# d'abord le dev
DEV=$(awk -F":" '{print $1}' <<< "$ligne") # donne aussitôt /dev/sda1
DEV=${DEV%%[[:blank:]]*} # supprime les [[:blank:]] en fin de dev (cas saisie manuelle)
# pour les autres , à cause d'espaces possibles (dans le label)
# et il faut mettre un espace avant pour chaque cas LABEL et non PARTLABEL UUID et non PARTUUID ...
if grep " LABEL" <<< "$ligne"
then
LABEL=$(echo "$ligne"|sed -r 's/.*\bLABEL="([^"]+)".*/\1/')
else
LABEL=""
echo "pas de LABEL"
fi
if grep " UUID" <<< $ligne
then
UUID=$(echo "$ligne"|sed -r 's/.*\bUUID="([^"]+)".*/\1/')
else
UUID=""
echo "pas d'UUID"
fi
if grep " TYPE" <<< $ligne
then
TYPE=$(echo "$ligne"|sed -r 's/.*\bTYPE="([^"]+)".*/\1/')
else
TYPE=""
echo "pas de type"
fi
[[ -z `grep "^\/dev" <<< $DEV` ]] && echo \
&& echo "il manque /dev dans la ligne $ligne du fichier de référence UUID-LABEL" \
&& exit 0
dev[maxuuid]=$DEV #dev,label,uuid,type dans des tableaux de la ligne
label[maxuuid]="$LABEL"
uuid[maxuuid]="$UUID"
btype[maxuuid]="$TYPE"
done < $blkid_choisi
##############################################################################
if [[ "$blkid_choisi" != "$blkid" ]]
then
verifier_presence_dev # vérifie que tous les dev du fichier choisi sont bien déclarés
fi
###############################################################################
# sortie des uuid label pour info
[[ -e "tmp-u-l.txt" ]] && rm "tmp-u-l.txt"
echo
p=0
while [[ $p -le $maxuuid ]]
do
aff_dev="${dev[$p]}" && [[ -z "$aff_dev" ]] && aff_dev="_"
aff_label="${label[$p]}" && [[ -z "$aff_label" ]] && aff_label="___"
aff_uuid="${uuid[$p]}" && [[ -z "$aff_uuid" ]] && aff_uuid="___"
aff_btype="${btype[$p]}" && [[ -z "$aff_btype" ]] && aff_btype="___"
# car si l'un des $ est "" , il y a erreur d'affichage
printf "%02s %-10s UUID %-36s LABEL: %-20s TYPE : %-10s\n" \
"$p" "$aff_dev" "$aff_uuid" "$aff_label" "$aff_btype" | tee -a tmp-u-l.txt
((p++))
done
titre="Affichage des concordances LABEL <=> UUID Visualiser puis Valider pour continuer"
zenity --text-info --title "$titre" --filename "tmp-u-l.txt" --height "640" --width "1280" --font "Courier New Bold 10"
code=$?
[[ -e "tmp-u-l.txt" ]] && rm "tmp-u-l.txt" # supprime ce fichier devenu inutile
if [[ $code -ne 0 ]]
then
echo $code
exit 0 #sortie si on ne valide pas
else
echo $code
fi
################ début de traitement du fichier GRUB ###############################
# Quel fichier grub traiter ?
titre="$0 Sélectionnez le fichier GRUB à traiter"
fich_source=`zenity --file-selection --filename="../fichier-grub/*" --title="$titre"`
case $? in # $? est le code de retour de zenity
0) : ;;
1) echo "Aucun fichier sélectionné." ; exit 1 ;;
-1) echo "Une erreur inattendue est survenue." ; exit 1 ;;
*) echo "erreur non reconnue" ; exit 1 ;;
esac
# $fich_source est de la forme /media/SH/grub/fichier-grub/grub-2UUID.cfg
# servira à préciser les fichiers grub-OK,grub-sup
precision=$(sed 's/\//-/g' <<< "$fich_source") # remplace les / par des -
# /media/SH/grub/fichier-grub/grub-2UUID.cfg
# precision devient -media-SH-grub-fichier-grub-grub-2UUID.cfg
fich_sauv="$ZZZnum/grub-OK-$num$precision.txt"
fich_sup="$ZZZnum/grub-sup-$num$precision.txt"
fich_transforme="$ZZZnum/grub-mod-$num$precision.txt"
#### lecture et traitement du fichier GRUB #######
trier_fichier # création des 3 fichiers de 1 à 10 linux 10 linux à 40 custom 40 custom à la fin
################# traitement jusqu'à 10_linux #####################
IFS="~"
prem=0
while read ligne
do
((nb_lignes_lues++))
if [[ $prem -eq 0 ]]
then
modif_ligne1_grub "$ligne" ; ((prem++))
else
echo $ligne >> "$fich_sauv"
((nb_lignes_cons++))
((nb_lignes_hors_menu++))
fi
done < "$fich_source_0"
################# traitement de 10_linux à 40_custom
while read ligne
do
((nb_lignes_lues++))
if [[ $prem -eq 0 ]] # pourrait être supprimé depuis V34
then
modif_ligne1_grub "$ligne" ; ((prem++))
else
# entre les crochets on a tab et espace élargisement après {
res=`echo "$ligne" | grep "^[[:blank:]]*menuentry.*{[[:blank:]]*$"`
mem=`echo "$ligne" | grep "^[[:blank:]]*menuentry ['\"]Memory test.*{[[:blank:]]*$"`
# res=`echo "$ligne" | grep "^[ ]*menuentry.*{[ ]*$"`
# mem=`echo "$ligne" | grep "^[ ]*menuentry ['\"]Memory test.*{[ ]*$"`
# res est vide s'il n'y a pas menuentry {
# mem est non vide si on a Memory test -ne pas traiter menuentry 'Memory test
if [[ -n $mem ]]
then # si Memory test on force res à vide
res=""
fi
if [[ -z $res ]]
then # pas menuentry
subm=`echo "$ligne" | grep "^[[:blank:]]*submenu.*{[[:blank:]]*$"`
# subm=`echo "$ligne" | grep "^[ ]*submenu.*{[ ]*$"`
if [[ -z $subm ]]
then # pas menuentry pas submenu
echo "$ligne" >> $fich_sauv # écriture de cette ligne dans sauv
((nb_lignes_cons++)) # stat
((nb_lignes_hors_menu++)) # stat
echo -e ".\c" # trace écran
else # contient submenu
echo -e "S\c" # trace
traite_ligne_submenu "$ligne" # traitement de submenu
fi
else # on a menuentry
lire_menuentry # mettre en mémoire dans menu[0..n]
trt_menu2 "${menu[0]}" # rem : 1 si /dev/sd /dev/sd
code_dev_dev=$?
if [[ $code_dev_dev -eq 1 ]] # si 1 on supprime
then # le bloc menuentry contient /dev /dev
sort_menu_1 " " "menu supprimé : trop de /dev/sd" # fich_sup
((nb_menu_sup++))
else # menuentry ne contient pas /dev/sd /dev/sd
critere_suppression_2 # analyse des uuid et recherche de label
code_crit2=$?
case $code_crit2 in
0) # les uuid sont égaux
transforme_ligne_menuentry "$chaine_search" # mettre un label dans menu[0]
sort_menu_0 # écrire le menu dans fich_sauv
((nb_menu_cons++)) # stat
;;
1) # menu sans modif (ni search ni linux)
sort_menu_0 # écrire le menu dans fich_sauv
sort_info_transforme "${menu[0]}" "menu conservé (pas de ligne search ou linux)"
((nb_menu_cons++)) # stat
;;
2) # uuid différents on supprime ce menu
sort_menu_1 " " "menu supprimé : uuid différents" # écrire dans fich_sup
((nb_menu_sup++)) # stat
;;
3) # uuid non trouvé (search et linux existent)
sort_menu_0 # écrire le menu dans fich_sauv
sort_info_transforme "${menu[0]}" "menu conservé : UUID search ou linux non trouvé dans $blkid_choisi"
((nb_menu_cons++)) # ce menu étant conservé
((nb_menu_sans_uuid++))
;;
4) # uuid != mais boot séparé
transforme_ligne_menuentry "$chaine_linux" # met label dans menu[0]
sort_menu_0 # écrire le menu dans fich_sauv
((nb_menu_cons++)) # stat non prévu dans memorise_menuentry
((nb_menu_boot_cons++))
;;
esac
fi # [[ $code_dev_dev -eq 1 ]]
fi #[[ -z $res ]]
fi #[[ $prem -eq 0 ]]
done < "$fich_source_1"
echo $nb_lignes_lues
################# traitement 40_custom à fin #####################
if [[ -e "$fich_source_2" ]] # en cas d'essai sans ligne 40_custom
then
while read ligne
do
((nb_lignes_lues++))
((nb_lignes_cons++))
((nb_lignes_hors_menu++))
echo $ligne >> "$fich_sauv"
done < "$fich_source_2"
fi
#################################################################
IFS="$OLDIFS"
echo "###################################################################" | tee -a "$fich_stat"
printf "%-40s %s\n" "fichier traité" " : " | tee -a "$fich_stat"
echo "$fich_source" | tee -a "$fich_stat"
printf "%-40s %s\n" "le résultat se trouve dans" " : " | tee -a "$fich_stat"
echo "$fich_sauv" | tee -a "$fich_stat"
echo | tee -a "$fich_stat"
printf "%-39s %s %5d\n" "nombre de lignes lues" " : " "$nb_lignes_lues" | tee -a "$fich_stat"
printf "%-40s %s %5d\n" "lignes conservées" " : " "$nb_lignes_cons" | tee -a "$fich_stat"
printf "%-40s %s %5d\n" "lignes supprimées" " : " "$nb_lignes_sup" | tee -a "$fich_stat"
printf "%-40s %s %5d\n" "lignes modifiées" " : " "$nb_lignes_mod" | tee -a "$fich_stat" # ajout V46++
if [[ $nb_lignes_sup -gt 0 ]]
then
printf "%-40s %s\n" "fichier des lignes supprimées" " : " | tee -a "$fich_stat"
echo "$fich_sup" | tee -a "$fich_stat"
echo | tee -a "$fich_stat"
fi
printf "%-40s %s %5d\n" "nombre de menus conservés" " : " "$nb_menu_cons" | tee -a "$fich_stat"
printf "%-40s %s %5d\n" "nombre de menus supprimés" " : " "$nb_menu_sup" | tee -a "$fich_stat"
printf "%-40s %s %5d\n" "nombre de menus avec boot conservés" " : " "$nb_menu_boot_cons" | tee -a "$fich_stat"
if [[ $nb_menu_sans_uuid -gt 0 ]]
then
printf "%-40s %s %5d\n" "nombre de menus sans uuid trouvé" " : " "$nb_menu_sans_uuid" | tee -a "$fich_stat"
fi
echo | tee -a "$fich_stat"
printf "%-40s %s %5d\n" "lignes conservées (hors menu)" " : " "$nb_lignes_hors_menu" | tee -a "$fich_stat"
printf "%-40s %s %5d\n" "lignes conservées (menu)" " : " "$nb_lignes_menu_cons" | tee -a "$fich_stat"
echo "###################################################################" | tee -a "$fich_stat"
echo "après avoir vérifié manuellement le fichier"
echo "$fich_sauv"
echo "en réel vous pourrez remplacer grub.cfg à vos risques et périls"
echo | tee -a "$fich_stat"
texte_attention=""
if [[ $fich_source =~ /boot/grub/grub.cfg$ ]]
then
texte_attention_grub_reel="====> Attention vous avez choisi de traiter un fichier grub réel
/boot/grub sera remplacé par le fichier résultant ... prenez vos précautions
mais je rapelle qu'une sauvegarde du grub original est effectué
donc récupérable"
fi
rep=""
while [[ $rep != [oOyYnN] ]]
do
################ mise à jour du fichier traité ou non ###########################
titre=" ################ remplacement de GRUB ###########"
texte="
Voulez-vous remplacer le fichier choisi
$fich_source
par le nouveau fichier généré
$fich_sauv
par précaution si vous répondez oui le fichier
$fich_source (fichier original choisi)
sera sauvegardé dans
$fich_source-$num
puis
$fich_source
sera remplacé par le contenu du fichier
$fich_sauv
$texte_attention_grub_reel
répondez par (oOyYnN)"
rep=`zenity --entry --title "$titre" --text "$texte" --width "800"`
case $rep in
[oOyY] ) # sauvegarde de "grub" , je conserve $num
echo "
vous avez demandé le remplacement du fichier
OK mais avant je sauvegarde le fichier original
$fich_source
dans
$fich_source-$num
(mot de passe administrateur requis)
sudo cp "$fich_source" "$fich_source-$num""
sudo cp "$fich_source" "$fich_source-$num"
code=$?
if [[ $code != 0 ]]
then
echo "il y a eu un problème lors de la sauvegarde du fichier
(code erreur : $code)"
suppression_fichiers_temporaires
echo "je sors"
exit 0
fi
#et fich_sauv remplace grub
echo "
OK je remplace
$fich_source
par
$fich_sauv
(mot de passe administrateur requis)
sudo mv "$fich_sauv" "$fich_source""
sudo mv "$fich_sauv" "$fich_source"
code=$?
if [[ $code != 0 ]]
then
echo "il y a eu un problème lors du remplacement du fichier $fich_source
(code erreur : $code)"
suppression_fichiers_temporaires
echo "je sors"
exit 0
else
echo
echo "fichier $fich_source remplacé"
fi
;;
[nN] )
echo ; echo "fichier oiginal non remplacé"
echo " mais le fichier résultant"
echo " $fich_sauv"
echo " est à disposition"
;;
* ) echo "utilisez seulement oOyYnN S.V.P."
;;
esac
done
suppression_fichiers_temporaires
echo "taper entrée pour terminer"
read g #pour attendre
exit 0
Dernière modification par ar barzh paour (Le 22/04/2020, à 16:37)
PC : B760M DS3H DDR4, 12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : Intel(R) Core(TM)2 Duo CPU T6570 @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 22.04 ( en voyage )
Portable2 : T5750 @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )
Hors ligne
#179 Le 16/04/2020, à 17:30
- ar barzh paour
Re : [Projet terminé] correction anomalie de grub
le fichier recup_fstab_V8
#!/bin/bash
# V8+ 2020 ajout de espace (grep " LABEL" au lieu de "LABEL" et les autres ) dans recup label uuid type
# V8 2018-11-23 utilisation de sed -r 's/.*\bLABEL="([^"]+)".*/\1/'
# V1 récupère le contenu des fichiers fstab qui peuvent exister sur la machine
# comment ?
# récupération des dev présents par blkid
# création du fichier blkid-res.txt
# pour les partitions déjà montées (via mount)
# lecture et traitement de <partition>/etc/fstab
# et pour chacune des autres partitions
# montage
# lecture et traitement de <point de montage>/etc/fstab
# démontage
# le traitement consiste à écrire dans le fichier DevSd_UBoot_UPart.txt
# pour chaque partition qui sera reconnue comme ayant un boot séparé
# DevSd="/dev/sdxx" UPart="uuid de la partition avec boot" UBoot="uuid du boot"
# le traitement consiste à écrire dans le fichier DevSd_Uboot_Upart-date.txt
# pour chaque partition qui sera reconnue comme ayant un boot séparé
# DevSD="/dev/sdxx" UBoot="uuid du boot" UPart="uuid de la partition avec boot"
# V2 création fichier UBoot_UPart contenant les uuid d'un système avec boot séparé
# format uuid1-uuid2 et uuid2-uuid1 servira lors du traitement modif-grub
# V3 remise en forme
# V4 supprime aussi les fichiers inutiles
# les fichiers créés sont
# UBoot-Upart.txt blkid-res.txt
# et dans ZZZnum : UBoot_Upart-<date>.txt DevSd_UBoot_UPart-<date>.txt
# V5 pour des raisons d'affichage , les _ des noms de fichiers sont remplacés par des -
# V6 2018/02 vérifie les doublons label et uuid
function OK {
# à cause de problème d'affichage
#declare ffich_fstab_conc=$(sed "s/[_ ]/*/g" <<< $fich_fstab_conc)
#declare fres_blkid=$(sed "s/[_ ]/*/g" <<< $res_blkid)
#declare ffich_fstab_long=$(sed "s/[_ ]/*/g" <<< $fich_fstab_long)
#declare ffich_recup=$(sed "s/[_ ]/*/g" <<< $fich_recup)
reponse=""
while [[ $reponse != [oOyYnN] ]]
do
titre="programme $0"
texte="
sous programme $0
0- ===> il est préférable pour un résultat plus correct
de partir d'un fichier grub.cfg tout neuf
donc auparavant , lancer un sudo update-grub
1-le but principal de ce sous programme est de créer un fichier
$fich_fstab_conc
qui contiendra les uuid des systèmes qui ont un boot séparé
2-il met a disposition le fichier
$res_blkid
qui contient le résultat de la commande sudo blkid
3-il crée aussi (pour info d'analyse) le fichier
$fich_fstab_long
qui contient le fichier $fich_recup des partitions présentes
comment ?
- récupération des dev existants par sudo blkid
- pour les partitions déjà montées (via mount)
lecture et traitement de <partition>/etc/fstab
- pour chacune des partitions non montées (sauf ntfs , swap)
montage
lecture et traitement de <point de montage>$fich_recup
démontage
SOUS-PROGRAMME RECUP DE MODIF GRUB
tapez O puis valider pour continuer
tapez A puis valider pour arrêter
O pour continuer / A pour arrêter le programme"
reponse=`zenity --entry --title "$titre" --text "$texte" --width "800"`
case $reponse in
[oOyY] ) : ;;
[aAnN] ) exit 1 ;;
* ) echo "utilisez seulement oOyYaAnN S.V.P." ;;
esac
done
}
# affiche le fichier des doublons trouvés et demande s'il faut continuer ou non
function continuer {
titre="$1"
texte="
$(cat $fich_double_label_uuid)
Continuer quand même ? Répondez par : (oOyYnNaA) "
reponse=""
while [[ $reponse != [oOyYnNaAcC] ]]
do
reponse=`zenity --entry --title "$titre" --text "$texte" --width "800"`
case $reponse in
[oOyY] ) : ;;
[aAnN] ) exit 65 ;;
* ) echo "utilisez seulement oOyYaAnN S.V.P." ;;
esac
done
}
function rech_uuid_dev { # si $1 est dans dev[] renvoi l'uuid correspondant
for i in ${!dev[@]}
do
[[ "$1" = ${dev[$i]} ]] && uuid=${uuid[$i]} && break
done
}
function rech_uuid_label { # si $1 est dans label[] renvoi l'uuid correspondant
for i in ${!dev[@]}
do
[[ "$1" = ${label[$i]} ]] && uuid=${uuid[$i]} && break
done
}
function ecrit_uuid1_uuid2 { # recoit $1 $2 sous la fore UUID= ou LABEL= ou /dev/sdxx
# écrit uuid1-uuid2 et uuid2-uuid1 dans $fich_fstab_conc
# en remplacant le label ou le /dev/sdxx par l'uuid correspondant
# et en enlevant UUID= et LABEL=
uuid1=""
uuid2=""
echo "fonction ecrit_uuid1_uuid2 $1 $2"
#pour le premier paramètre
debut=`echo "$1" | cut -c1-5`
uuid=""
case "$debut" in
\/dev\/ )
rech_uuid_dev "$1" # /dev/sdxx on recherche l'uuid correspondant
uuid1="$uuid"
;;
UUID\= )
uuid1=`echo "$1" | cut -c6-` # si UUID= on prend ce qui se trouve après =
;;
LABEL )
rech_uuid_label `echo "$1" | cut -c7-` # si LABEL on prend ce qui se trouve après =
uuid1="$uuid" # et on recherche l'uuid correspondant
;;
esac
#même chose pour le deuxième paramètre
debut=`echo "$2" | cut -c1-5`
uuid=""
case "$debut" in
\/dev\/ )
rech_uuid_dev "$2" # /dev/sdxx on recherche l'uuid correspondant
uuid2="$uuid"
;;
UUID\= )
uuid2=`echo "$2" | cut -c6-` # UUID= on prend ce qui se trouve après =
;;
LABEL )
rech_uuid_label `echo "$2" | cut -c7-` # LABEL on prend ce qui se trouve après =
uuid2="$uuid" # et on recherche l'uuid corespondant
;;
esac
if [[ -n $uuid1 ]] && [[ -n $uuid2 ]]
then
# on écrit les deux combinaisons possibles , plus simple à traiter ensuite
echo $uuid1-$uuid2 >> $fich_fstab_conc
echo $uuid2-$uuid1 >> $fich_fstab_conc
fi
echo "fin de fonction ecrit_uuid1 uuid2 =1=>$uuid1<=== =2=>$uuid2<==="
}
function ecrit_ligne_court { # si $3 (UBoot) non vide
# uuid1-uuid2 dans UBoot_UPart
if [[ -n "$3" ]] # si uboot non vide
then
ecrit_uuid1_uuid2 "$2" "$3" # envoie uuid de partition et uuid de boot
fi
}
function trans_ligne_fstab { # récupère les champs d'une ligne
# champ1 champ2 champn mais on ne s'intérese qu'aux champs 1 et 2
# champ1 : UUID=uuid ou LABEL=label ou le dev [non traités : PARTUUID= PARTLABEL=]
# champ2 : le point de montage
champ1=`echo "$1"|awk -F" " '{printf ("%s",$1)}'` # bloc spécial ou système de fichiers distant à monter
champ2=`echo "$1"|awk -F" " '{printf ("%s",$2)}'` # c'est le point de montage
case "$champ2" in
\/ )
dev_part=$champ1 # si champ2 est / on positionne dev_part sur champ1
;;
\/boot )
dev_boot=$champ1 # si champ2 est /boot on positionne dev_boot sur champ1
;;
esac
}
# début du programme
echo "début de programme $0 "
if [[ $# -eq 0 ]]
then
echo "sans le paramètre répertoire"
ZZZnum="ZZZnum"
else
echo "avec le paramètre répertoire $1"
ZZZnum="$1" # modif_grub doit envoyer ZZZnum
fi
echo "Répertoire : "$ZZZnum
! [[ -e "$ZZZnum" ]] && mkdir "$ZZZnum"
#########################################################################################
# variables
num=`date +%Y:%m:%d`-`date +%H:%M:%S`
res_blkid="blkid-res.txt" # résultat de sudo blkid
fich_fstab_long="$ZZZnum/DevSd-UBoot-UPart-$num.txt" # résultant commenté
fich_fstab_conc="UBoot-UPart.txt" # résultant concaténé UUID1-UUID2
fich_fstab_conc_num="$ZZZnum/UBoot-UPart-$num.txt" # sauvegarde,à supprimer manuellement
rep_mnt=/mnt/jpb-$num # répertoire pour montages/démontages
fich_recup=/etc/fstab # fichier à récupérer dans part.
fich_double_label_uuid="$ZZZnum/doublon.txt" # contient les label ou uuid truvés plusieurs fois
#########################################################################################
OK # présentation du programme / sortie ou non
reponse=""
while [[ $reponse != [oOyYnNaAcC] ]]
do
titre="récupération des UUID et LABEL des partitions des disques"
texte="
Récupération des infos dans les fichiers $fich_recup des partitions
ce programme travaille avec sudo pour
récupérer les dev (blkid)
effectuer des montages/démontages
(mot de passe d'administration requis)
répondez par
(oOyY) pour lancer la commande sudo blkid ( remise à jour du fichier)
(aA) pour arrêter ce programme
O pour récupérer les devices via \"sudo blkid\"
A Arrêter
"
reponse=`zenity --entry --title "$titre" --text "$texte" --width "800"`
case $reponse in
[oOyY] ) echo "sudo blkid" ; sudo blkid > $res_blkid ;;
[aA] ) echo "arrêt du programme" ; exit 1 ;;
* ) echo "$reponse utilisez seulement oOyYaA S.V.P." ;;
esac
done
rm "$fich_fstab_conc"
touch "$fich_fstab_conc"
#echo "# $num : couples uuid-boot - uuid-systeme des menuentry en boot séparé" > $fich_fstab_conc
# récupération des dev label et UUID
unset uuid
unset label
unset bdev # V31 pour boot séparé
unset bmont # pour le point de montage à cause du boot séparé
unset btype # le type de la partition
maxuuid=-1
while read ligne # lecture et traitement du fichier généré par sudo blkid
do
# c'est le même script que dans modif-grub
# certaine lignes sont inutiles mais je les ai laissées
[[ -z $ligne ]] && echo "ligne vide je passe" && continue # correction ligne vide
((maxuuid++))
# d'abord le dev
DEV=$(awk -F":" '{print $1}' <<< "$ligne") # donne aussitôt /dev/sda1
# pour les autres , à cause d'espaces possibles (dans le label)
# il faut mettre un espace devant chaque
# à cause de PARTLABEL par exemple
if grep " LABEL" <<< $ligne
then
# -r : utilisation Ere de sed
# ([^"]+) mémorise suite non nulle de caractères différents de "
# \b devant la chaine pour indique une chaine vide ? (moi j'aurais mis espace)
LABEL=$(echo ${ligne}|sed -r 's/.*\bLABEL="([^"]+)".*/\1/')
else
LABEL=""
echo "pas de LABEL"
fi
if grep " UUID" <<< $ligne
then
UUID=$(echo ${ligne}|sed -r 's/.*\bUUID="([^"]+)".*/\1/')
else
UUID=""
echo "pas d'UUID"
fi
if grep " TYPE" <<< $ligne
then
TYPE=$(echo ${ligne}|sed -r 's/.*\bTYPE="([^"]+)".*/\1/')
else
TYPE=""
echo "pas de type"
fi
if grep " PARTUUID" <<<$ligne
then
PARTUUID=$(echo ${ligne}|sed -r 's/.*\bPARTUUID="([^"]+)".*/\1/')
else
PARTUUID=""
echo "pas de partuuid"
fi
[[ -z `grep "^\/dev" <<< $DEV` ]] && echo \
&& echo "il manque /dev dans la ligne $ligne du fichier de référence UUID-LABEL" \
&& exit 1
# init variables d indice maxuuid
dev[maxuuid]=$DEV # le dev de la ligne blkid
label[maxuuid]="$LABEL" # le label de la ligne blkid
uuid[maxuuid]="$UUID" # l uuid de la ligne blkid
btype[maxuuid]="$TYPE" # le type de la ligne blkid
mnt_dev[maxuuid]="1" # modifié par mount : 0 si le dev est monté
p_dev[maxuuid]="" # modifié par mount : point de montage
done <$res_blkid
# artifice pour créer un uuid en double
# uuid[11]="78684472684430E4"
# artifice pour créer un label en double
# label[8]="U16.04-b10-64b"
# mise à zéro du fichier
rm "$fich_double_label_uuid"
touch "$fich_double_label_uuid"
#vérifier l'unicité des LABEL dans le tableau label
for i in ${!label[@]}
do
for j in ${!label[@]}
do
[[ $i -ne $j ]] && [[ ${label[$i]} = ${label[$j]} ]] && [[ -n ${label[$i]} ]] && echo "${dev[$i]} ${label[$i]} ${uuid[$i]}" >> "$fich_double_label_uuid"
done
done
#vérifier l'unicité des UUID ( cas de disques ajoutés ) dans le tableau uuid
for i in ${!uuid[@]}
do
#echo ${uuid[$i]}
for j in ${!uuid[@]}
do
#echo ${uuid[$i]} ${uuid[$j]}
[[ $i -ne $j ]] && [[ ${uuid[$i]} = ${uuid[$j]} ]] && [[ -n ${uuid[$i]} ]] && echo "${dev[$i]} ${label[$i]} ${uuid[$i]}" >> "$fich_double_label_uuid"
done
done
# si le fichier n'est pas vide , avertir et sortir si demande
[[ -s "$fich_double_label_uuid" ]] && continuer "ATTENTION LABEL et/ou UUID en DOUBLE"
#récupération des partitions déjà montées
mount | grep '^\/dev' > tmp.txt
# 1 2 3 4 5 6
# /dev/sda11 on /media/SH type ext4 (rw,relatime,data=ordered)
# remarque :
# awk -F" " '{printf ("%s ",$1)}' tmp.txt
# donne
# tous les dev séparés par une espace grace à "%s "
# awk -F" " '{printf ("%s ",$3)}' tmp.txt
# donne
# tous les points de montage séparés par une espace grace à "%s "
mdev=(`awk -F" " '{printf ("%s ",$1)}' tmp.txt`) # les dev montés dans un tableau
mont=(`awk -F" " '{printf ("%s ",$3)}' tmp.txt`) # les points de montage dans un tableau
rm "tmp.txt"
# positionnement montée ou non de chaque dev
for i in ${!dev[@]} # pour tous les indices des dev
do
for j in ${!mdev[@]} # pour tous les indices des partitions montées
do
if [[ "${dev[$i]}" = "${mdev[$j]}" ]]
then
mnt_dev[i]="0" # 0 indique que le dev est montée
p_dev[i]=${mont[$j]} # le point de montage du dev
break
fi
done
done
# sortie des uuid label pour info
[[ -e "tmp_u_l.txt" ]] && rm "tmp_u_l.txt"
echo
p=0
while [[ $p -le $maxuuid ]]
do
aff_dev="${dev[$p]}" # jamais vide
aff_mnt_dev="${mnt_dev[$p]}" # vaut 0 (monté) ou 1 (non monté)
aff_p_dev="${p_dev[$p]}" # (affichage en fonction du précédent)
# pour les corrections d'affichage
aff_uuid="${uuid[$p]}" && [[ -z "$aff_uuid" ]] && aff_uuid="_"
aff_label="${label[$p]}" && [[ -z "$aff_label" ]] && aff_label="_"
aff_btype="${btype[$p]}" && [[ -z "$aff_btype" ]] && aff_btype="_"
case $aff_mnt_dev in
0)
printf "%02s %-10s %-36s LABEL %-20s sur %-20s TYPE : %-10s\n" "$p" "$aff_dev" "$aff_uuid" "$aff_label" "$aff_p_dev" "$aff_btype" | tee -a tmp_u_l.txt ;;
1)
printf "%02s %-10s %-36s LABEL %-20s TYPE : %-10s\n" "$p" "$aff_dev" "$aff_uuid" "$aff_label" "$aff_btype" | tee -a tmp_u_l.txt ;;
esac
((p++))
done
reponse=""
titre="concordances dev<=>LABEL<=>UUID<=>point de montage (de blkid) Visualiser puis Valider pour continuer"
zenity --text-info --title "$titre" --filename "tmp_u_l.txt" --height "640" --width "1280" --font "Courier New Bold 10"
code=$?
[[ -e "tmp_u_l.txt" ]] && rm "tmp_u_l.txt" # supprime ce fichier devenu inutile
if [[ $code -eq 0 ]]
then
echo "OK je continue"
else
echo ; echo "Annulation demandée" ; echo ; exit 63
fi
##################################################
# pour cette partie il est absolument nécessaire d'avoir une liste des dev corrects
# d'où le sudo blkid effectué plus haut !
##################################################
echo "récupération des fstab de toutes les partitions" > $fich_fstab_long
echo >> $fich_fstab_long
############################################################
echo "pour les partitions déjà montées :" >> $fich_fstab_long
echo ${!dev[@]}
for i in ${!dev[@]} # pour tous les indices du tableau dev
do
echo $i ${dev[$i]} ${mnt_dev[$i]}
[[ ${mnt_dev[$i]} = "1" ]] && continue # non monté suivant !
[[ ${btype[$i]} = "ntfs" ]] && continue # ntfs suivant !
[[ ${btype[$i]} = "swap" ]] && continue # swap suivant !
# on pourrait en ajouter d'autres
echo >> $fich_fstab_long
echo ${dev[$i]} "montée sur" ${p_dev[$i]} >> $fich_fstab_long
#pour chaque dev monté on récupére les infos de fstab
fich=${p_dev[$i]}$fich_recup
fich=`sed 's/\/\//\//g' <<< $fich` # supprime les doubles // (à cause de //etc/fstab)
echo $fich #soit /etc/fstab soit /xxx/xxx/etc/fstab
if [[ -e $fich ]]
then
echo >> $fich_fstab_long
echo "$fich de ${dev[$i]}" >> $fich_fstab_long
# on ne garde que les lignes non commentées et non vide
dev_part=""
dev_boot=""
while read l_fstab
do
tmp=` grep '^[[:blank:]]*\#' <<< $l_fstab`
#si tmp n est pas vide , elle commence par #
if [[ -z $tmp ]] && [[ -n $l_fstab ]]
then
echo $l_fstab >> $fich_fstab_long
trans_ligne_fstab "$l_fstab"
fi
done < $fich
ecrit_ligne_court "${dev[$i]}" "$dev_part" "$dev_boot"
else
echo >> $fich_fstab_long
echo "pour ${dev[$i]} (${label[$i]}) /etc/fstab est inexistant" >> $fich_fstab_long
fi
done
echo >> $fich_fstab_long
##############################################################
echo "pour les partitions non montées :" >> $fich_fstab_long
if [[ -e "/mnt" ]]
then
echo "réperoire /mnt présent"
else
echo "le répertoire /mnt n'existe pas !!!"
exit 1
fi
rep_mnt_tmp="/mnt/jpb-$num"
echo "création du répertoire $rep_mnt_tmp pour monter les partitions"
sudo mkdir $rep_mnt_tmp
for i in ${!dev[@]} # pour tous les indices du tableau dev
do
echo $i ${dev[$i]}
[[ ${mnt_dev[$i]} = "0" ]] && continue # montée suivant !
[[ ${btype[$i]} = "ntfs" ]] && continue # ntfs suivant !
[[ ${btype[$i]} = "swap" ]] && continue # swap suivant !
echo
echo "traitement de $i ${dev[$i]} (${btype[$i]})"
echo "montage de ${dev[$i]} sur $rep_mnt_tmp"
sudo mount ${dev[$i]} $rep_mnt_tmp
code=$?
echo "code de retour montage de ${dev[$i]} sur $rep_mnt_tmp : $code"
if [[ $code = 0 ]] # si le montage est réussi
#################### montage réussi ####################
then
fich=$rep_mnt_tmp/etc/fstab
if [[ -e $fich ]]
then
echo >> $fich_fstab_long
echo ${dev[$i]} montée sur $rep_mnt_tmp >> $fich_fstab_long
dev_part=""
dev_boot=""
while read l_fstab
do
tmp=` grep '^[[:blank:]]*\#' <<< $l_fstab`
# si ne commence pas par # , tmp est vide
# et si la ligne n'est pas vide on l'écrit
if [[ -z $tmp ]] && [[ -n $l_fstab ]]
then
echo $l_fstab >> $fich_fstab_long
trans_ligne_fstab "$l_fstab"
fi
done < $fich
ecrit_ligne_court "${dev[$i]}" "$dev_part" "$dev_boot"
else
echo >> $fich_fstab_long
echo "pour ${dev[$i]} (${label[$i]}) /etc/fstab est inexistant" >> $fich_fstab_long
fi
# puis on le démonte avec boucle sinon le démontage ne se fait pas toujours
boucle=0
code=1
while [[ $code -ne 0 ]]
do
sudo umount "$rep_mnt_tmp"
code=$?
echo "boucle $boucle : ${dev[$i]} code de retour de umount $code"
if [[ $code = 0 ]]
then
echo
echo "boucle $boucle : ${dev[$i]} démontage effectué (code retour $code)"
ls -ails $rep_mnt_tmp
else
echo
echo "boucle $boucle : ${dev[$i]} non démonté (code retour $code)"
sleep 1 # attente en cas de non démontage
((boucle++))
if [[ $boucle -ge 10 ]]
then
echo "problème de démontage de ${dev[$i]}"
exit 1
fi
fi
done # boucle while
############################ échec de montage ###################
else
echo >> $fich_fstab_long
echo "impossible de monter ${dev[$i]} code echec de montage :$code" >> $fich_fstab_long
fi
done # boucle for i dev
echo ; echo
echo "fin de récupération des données de /etc/fstab des partitions présentes sur la machine"
echo ; echo
# sauvegarde de UBoot_UPart pour une utilisation personnelle
cp "$fich_fstab_conc" "$fich_fstab_conc_num"
echo "suppression du répertoire $rep_mnt_tmp en cours"
sudo rmdir $rep_mnt_tmp
code=$?
if [[ $code -ne 0 ]]
then
#rmdir: échec de suppression de '/mnt/jpb-2017:03:11-12:02:43': Périphérique ou ressource occupé
echo
ls -ails /mnt/jpb*
echo "vérifier le contenu du répertoire /mnt/jpb"
echo "faire le ménage dans ce répertoire"
exit 1
fi
echo "suppression réussie"
echo "fin normale du programme $0"
PC : B760M DS3H DDR4, 12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : Intel(R) Core(TM)2 Duo CPU T6570 @ 2.10GHz RAM 4GiB DDR2 667 MHz Ubuntu 22.04 ( en voyage )
Portable2 : T5750 @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )
Hors ligne