Travail terminé, corrections

Alors, encore une demande de correction complète avec le système '${REPLY}'
Je n’ai pas fait exactement comme tu m’as montré, Michel mais les tests sont bons.
Par contre, je n’ai pas trouvé le moyen de concaténer ça :

Il refuse [ -e “${ddext[*]}” ]. Je pense que la donnée vide pour passer au [1] directement est la cause ?[code]#!/bin/bash

BEGIN INIT INFO

Nom du script : sauvegarde

Auteur : Ricardo, aidé de l’équipe de ‘debian-fr.org

Date de création : juillet 2011

Utilité : faciliter les sauvegardes

Version : cette version est écrite pour l’utilisation avec deux partitions de sauvegarde, à alterner dans le temps.

#+ Il est souhaitable que ces partitions soient sur un DD différent de celui qui abrite le système

Pre-requis : voir tuto = http://www.debian-fr.org/sauvegarde-clonage-d-une-sid-t25179.html

Description : script permettant d’effectuer, régulièrement et de façon simple, les sauvegardes de son système

Droits : entièrement libres mais en cas de copie, la citation de “debian-fr.org” nous serait agréable

Modifié le :

Objet de la modification :

END INIT INFO

#---------------------------------------------
function test_sauvegarde()
{

Teste si la sauvegarde a abouti (premier paramètre = 0), sinon, on sort.

if (("$1" > 0))
then
	printf "\nErreur lors de la sauvegarde de %s\n" "$2" >&2
	exit 1
else
	printf "\nSauvegarde de %s : OK\n" "$2"
fi

}
#-----------------Variables-------------------
mount_rep="/mnt/autre"

la première donnée, vide, figure le [0], de façon à commencer par [1]

ddext=(’’ ‘/dev/sdb9’ ‘/dev/sdb10’)
systeme_fich=(’’ ‘ext3’ ‘ext2’)
controle=(’’ ‘/home/controle’ ‘/home/controle-ricardo’)
exclure=(’’ ‘/root/exclure’ ‘/home/ricardo/.exclure’)
sauve=(’’ ‘/mnt/autre/sauve’ ‘/mnt/autre/sauve-ricardo’)
#---------------------------------------------

Teste l’existence des partitions de sauvegarde et celle du dossier de montage, sinon, on sort avec erreur 1.

[ -e "${ddext[1]}" ] && [ -e "${ddext[2]}" ] || { echo "Le DDext ne répond pas !" >&2; exit 1; } 

mkdir -p "$mount_rep" || { echo "Le dossier de montage n'existe pas !" >&2; exit 1; }	

Choix de la sauvegarde. Si le montage ne s’effectue pas, on sort avec erreur 1.

deja_montee=0
PS3="Entrez le N° de la sauvegarde choisie : "
select sauvegarde in “sauve” “sauve2” quitter
do
case ${REPLY} in
[1-2])
index=${REPLY}
if ! grep -q “^${ddext[$index]} “$mount_rep” ${systeme_fich[$index]}” /etc/mtab
then
sudo mount -t “${systeme_fich[$index]}” “${ddext[$index]}” “$mount_rep” || exit 1;
break
else
printf "Info : La partition ${ddext[$index]} est déjà montée\n"
deja_montee=1
break
fi
;;
### 3) echo “On sort du menu”; break ###
;; 3) echo “On sort du script”; exit
*) echo “Saisie non valide !”
;;
esac
done

Teste si la corbeille est pleine (pésence de fichier(s) dans … /files), si elle l’est, liste les fichiers qu’elle contient

echo -e "\033[4mCONTENU de la CORBEILLE\033[0m\n"
if [ -e ~/.local/share/Trash/files/ ]
then
ls ~/.local/share/Trash/files
read -p "on peut la vider ? o/* : " corbeille
if [ “$corbeille” = o ]
then
rm -rf ~/.local/share/Trash/*
echo -e "\033[4mCORBEILLE VIDÉE\033[0m"
fi
else
echo "La corbeille est vide"
fi

Test de l’état de la sauvegarde avec la fonction “test_sauvegarde”, qui se chargera de quitter le script si celle-ci est KO

1er paramètre : $? = statut de la dernière commande, c.a.d le rsync

2nd paramètre : / puis ~/ = dossier à sauvegarder

read -p “prêt pour la sauvegarde ? o/* : " onyva
if [ “$onyva” = o ]
then
sudo rsync -av --del --backup --backup-dir=”${controle[1]}" --exclude-from="${exclure[1]}" / “${sauve[1]}“
test_sauvegarde $? /
sudo rsync -av --del --backup --backup-dir=”${controle[2]}” --exclude-from="${exclure[2]}" ~/ "${sauve[2]}"
test_sauvegarde $? ~/
else
exit 1
fi

Si la partition de sauvegarde était déjà montée lors de l’appel, on sort sans la démonter.

if [ "$deja_montee" = 0 ]
then 
	sudo umount "$mount_rep"
else
	sync
fi

[/code]

Salut !

Tu ne peux pas utiliser cette forme. En effet, l’operateur -e n’accepte qu’un seul fichier !

Pour utiliser ton tableau en un seul test c’est délicat …
J’ai bien une solution mais c’est en utilisant une notion que tu ne connais pas encore : la substitution de processus

Cela donne ceci :

Explications :

  • la substitution de processus : le script qui se trouve entre <( et ) est exécuté et le résultat est fourni dans un fichier temporaire valable uniquement le temps d’exécution du pipeline.
  • l’option -c de grep, permet de retourner le nombre de fois où les motifs ont été trouvé
  • l’option -f permet de dire à grep que les motifs à trouver se trouvent dans un fichier (ici, il est temporaire et le contenu est le résultat de printf “^%s$\n” “${ddext[@]}”)
  • printf “^%s$\n” “${ddext[@]}” : on affiche tous les éléments du tableau ddext sur des lignes indépendantes (une ligne=un élément).
  • enfin <(printf “%s\n” /dev/*) : permet de créer un fichier temporaire contenant tous les devices connus du système. La recherche des motifs s’effectuera dans ce fichier temporaire.

Au final, on demande à grep de compter la quantité de device contenus dans le tableau ddext que le système connait. Si cette quantité est différente du nombre d’élément (-1 car élément vide qui ne sera jamais trouvé) du tableau ddext, alors il y a une partition qui manque !

Ben il restera comme ça, en fait, c’est quand même assez clair.
Donc, en dehors de ça, c’est correct ?

Un test que je n’avais pas fait et qui demande modification :

Ça sort bien du menu mais pas du script, qui, lui, continue et qui amèmera obligatoirement à une erreur.
Que faut-il faire : ajouter un ‘exit 1’ au ‘breack’ ou remplacer le ‘breack’ par un ‘exit 1’ ?

Il te faut remplacer le break par un exit (pas exit 1 car il n’y a pas d’erreur, juste une sortie volontaire du script)

sinon, :clap: Oui, c’est bon !
mais :think: juste une dernière chose :

  • j’intégrerai le “rsync” dans la fonction test_sauvegarde(). De ce fait, les paramètres en entrée de la fonction seront différents et tu auras besoin d’un nouveau tableau dans lequel il y aura les dossiers à sauvegarder.

  • je remplacerai les 4 lignes “sudo rsync …/test_sauvegarde …/ sudo rsync …/ test_sauvegarde …” par une boucle qui parcourt les tableaux controle, exclure, <nouveau_tableau_contenant_les_dossiers_a_sauver> et sauve pour appeler la nouvelle version de test_sauvegarde

Ainsi, si tu veux ajouter des dossiers à sauvegarder, Il te faudra simplement ajouter les éléments dans tes tableaux et tu n’auras pas à modifier cette partie de code qui sera générique.

Pour la boucle :

for((index=1; index < ${#controle[@]}; index++))
do
  <appel de la nouvelle version de test_sauvegarde avec les nouveaux paramètres qui vont bien>
done

En fait, le ‘choix 3’ “sortir du menu” est-il indispensable ?
Il n’a pas de raison d’être car si on n’a pas choisi de N° utile (1 ou 2), la sauvegarde ne pourra pas avoir lieu.
Sinon, en cas qu’on pense ne pas être prêt et vouloir quitter. Faut être tordu quand même pour faire ainsi.

EDIT :
Allez, pour les “tordus”, je laisse quand même mais je modifie en “On sort du script”

EDIT 2 :
Pour le reste, je digère ça pendant tes vacances :laughing:

A mon sens, il faut laisser la possibilité de quitter le script “proprement”…(le script peut être lancé involontairement)

[quote=“ricardo”]
EDIT 2 :
Pour le reste, je digère ça pendant tes vacances :laughing:[/quote]
Comme tu veux mais Misterfreez (ou d’autres) est à même de prendre ma relève :whistle:

Bien sûr, et je tiens compte de l’avis de tous, c’est l’avantage de mon état, j’ai le choix, 3 ou 4 maîtres pour moi tout seul 8)
Pour le choix de “sortie”, je l’ai laissé en changeant “… menu” par “…script”.

Une fois ton travail terminé à 100%, ce script sera ajouté au wiki avec ton tuto??

Oui, il l’est déjà mais je vais le mettre à jour avec les données de quelques messages plus haut.

EDIT :
C’est fait, la dernire mouture est en ligne à
http://www.isalo.org/wiki.debian-fr/index.php?title=Script_de_double_sauvegarde_altern%C3%A9e

[quote=“ricardo”]EDIT :
C’est fait, la dernire mouture est en ligne à
http://www.isalo.org/wiki.debian-fr/index.php?title=Script_de_double_sauvegarde_altern%C3%A9e[/quote]
Le test hors du case je trouve ça plus joli (mais c’est cosmétique on s’en fout).

Je vois ceci dans la version du wiki :

sudo rsync -av --del --backup --backup-dir="${controle[1]}" --exclude-from="${exclure[1]}" / "${sauve[1]}" test_sauvegarde $? / sudo rsync -av --del --backup --backup-dir="${controle[2]}" --exclude-from="${exclure[2]}" ~/ "${sauve[2]}" test_sauvegarde $? ~/
Tu effectue toujours les deux sauvegardes ? Tu devrais pas utiliser $index ?

Edit : je viens de regarder la première version de ton script tu faire toujours les deux donc non pas de souci.

Par contre c’est vrai que du coup tu as deux fois les deux même lignes avec juste un numéro qui change…

Par ailleurs, si tu garde le test dans le case tu n’a pas besoin de la variable $index, tu peux directement utiliser $REPLY à la place.

Tu as raison, MisterFreez mais c’est la dernière suggestion de Totor et je ne l’ai pas encore étudiée.
Il y a d’ailleurs de forte chances pour que j’aie besoin de ton aide mais je vais d’abord essayer de comprendre seul.
Pas trop de temps ces jours-ci car mon fils aîné est à la maison avec femme et enfants :smiley:
Je t’appellerai en temps voulu :006
J’ai quand même mis en ligne sur le wiki car la version comme elle est fonctionne correctement, même si je sais qu’on peut encore améliorer.

EDIT :
Je viens de relire ta remarque sur l’utilisation de index, qui serait facilement applicable mais j’ai une question que je ne sais pas résoudre :
comment mutualiser la dernière donnée : ‘/’ et ‘~/’ ?

EDIT 2 :
à moins que ce soit le $2 de la fonction ?

[quote=“ricardo”]EDIT :
Je viens de relire ta remarque sur l’utilisation de index, qui serait facilement applicable mais j’ai une question que je ne sais pas résoudre :
comment mutualiser la dernière donnée : ‘/’ et ‘~/’ ?[/quote]
Avec une nouvelle liste par exemple ? :wink:

Je crois avoir compris la dernière proposition de Totor mais j’aimerais que tu m’expliques ce que je surligne en rouge.

[quote]- j’intégrerai le “rsync” dans la fonction test_sauvegarde(). De ce fait, les paramètres en entrée de la fonction seront différents et tu auras besoin d’un nouveau tableau dans lequel il y aura les dossiers à sauvegarder.

  • je remplacerai les 4 lignes “sudo rsync …/test_sauvegarde …/ sudo rsync …/ test_sauvegarde …” par une boucle qui parcourt les tableaux controle, exclure, <nouveau_tableau_contenant_les_dossiers_a_sauver> et sauve pour appeler la nouvelle version de test_sauvegarde

Ainsi, si tu veux ajouter des dossiers à sauvegarder, Il te faudra simplement ajouter les éléments dans tes tableaux et tu n’auras pas à modifier cette partie de code qui sera générique.

Pour la boucle :
Code:
for((index=1; index < ${#controle[@]}; index++))
do
<appel de la nouvelle version de test_sauvegarde avec les nouveaux paramètres qui vont bien>
done[/quote]

Tu compare « index » à la taille de controle.

En fait :
[ul]
[li]${controle[@]} : c'est tout les éléments de controle[/li]
[li]${#controle[@]} : c'est ça taille de controle[/li][/ul]

Tu compare « index » à la taille de controle.

En fait :
[ul]
[li]${controle[@]} : c’est tout les éléments de controle[/li]
[li]${#controle[@]} : c’est ça taille de controle[/li][/ul]

Salut !

[quote=“MisterFreez”][quote=“ricardo”]EDIT :
Je viens de relire ta remarque sur l’utilisation de index, qui serait facilement applicable mais j’ai une question que je ne sais pas résoudre :
comment mutualiser la dernière donnée : ‘/’ et ‘~/’ ?[/quote]
Avec une nouvelle liste par exemple ? :wink:[/quote]
Exactement :wink:
au passage, je préfère également le test en dehors du case mais comme tu dis, ce n’est que cosmétique et cela ne remet pas en question le fonctionnement du script.

la forme ${#nomVariable} donne le nombre de caractère de la valeur de la variable.
la forme ${#nomTableau[@]} donne le nombre d’éléments que le tableau contient :wink:

Merci pour les explications.
Pour l’emplacement du test, à l’intérieur du ‘case’, je l’y laisse comme ça ce script aura au moins une chose de Ricardo :laughing:
Encore besoin d’une explication :
Je ne comprends pas l’emplacement du ‘index++’, qui est je crois l’incrémentation, donc le passage de ‘index’ à ‘2’.
Dans les autres langages, cette incrémentation se fait APRES le ‘do’, non ?

pour index = 1
fait
<appel de la nouvelle version de test_sauvegarde …>
INCRÉMENTE index
recommence (donc repart du début avec la nouvelle donne, càd index = 2)

for((index=1; index < ${#controle[@]}; index++)) do <appel de la nouvelle version de test_sauvegarde avec les nouveaux paramètres qui vont bien> done

Explique-moi bien chaque signe car je ne perçois pas non plus la signification du ‘<’

Alors :wink:
le signe < a son sens 1er c.a.d inférieur (comparaison de nombre)

for((index=1; index < ${#controle[@]}; index++)) : on boucle tant que index est inférieur au nombre d’élément du tableau controle. au début index=1 et après chaque traitement de boucle, on l’incrémente de 1.

donc :

  • au premier tour de boucle : index vaut 1 et il y a 3 éléments dans le tableau controle (1 est bien inférieur à 3) --> sauvegarde avec les éléments ayant pour indice 1
  • au second tour, index vaut 2 et il y a toujours 3 éléments dans le tableau controle (et 2<3) --> sauvegarde avec les éléments ayant pour indice 2
  • au troisième tour, index est à 3 et il y a toujours 3 éléments dans le tableau controle. Par contre, 3 n’est pas inférieur à 3 donc on ne fait plus appel à la fonction

la nouvelle fonction doit recevoir en entrée toutes les informations en fonction de la sauvegarde à procéder car c’est elle qui réalise le rsync.
elle doit donc attendre :

  • la valeur de controle
  • la valeur de exclure
  • la valeur de sauve
  • le nom du dossier à sauvegarder (qui nécessite un nouveau tableau)

[quote=“ricardo”]Encore besoin d’une explication :
Je ne comprends pas l’emplacement du ‘index++’, qui est je crois l’incrémentation, donc le passage de ‘index’ à ‘2’.
Dans les autres langages, cette incrémentation se fait APRES le ‘do’, non ?[/quote]
En C99/C++/Java :

En C89 :

int i; for(i = 0; i < N; ++i) { }
En python :

En perl/php :

En ruby :

[code]for i in (1…N)
puts i
end

ou

1.upto(10) { |i| puts i } # par exemple il y en a d’autres
[/code]

Le do représente le bloc de code qui doit être exécuté à chaque itération (c’est léquivalent du { de la plupart des langages dans la plus part des cas).

Je comprends bien le développement et c’est ma mémoire qui déconne, une fois de plus.
Je pensais que l’appel à la fonction (donc le travail à effectuer en boucle), devait être placé entre le début et l’incrémentation.
Or là, l’incrémentation se fait avant l’appel à la fonction, ce qui me semble illogique.

EDIT :
Je ne remets pas en cause cette “logique” et je la comprends aussi :smiley: