Travail terminé, corrections

Comment placer les variables :

cont="/home/controle"
exclure="/root/exclure"
sauve="/mnt/autre/sauve"

dans cette ligne :question:

EDIT : je ne comprenais pas pourquoi ce qui suit ne fonctionnait pas :unamused:
tout simplement parce que j’avais oublié un ‘/’ en début de “sauve=”/mnt/autre/sauve""
Résolu donc :wink:

Est-ce que ~/ est bien interprété dans une ligne de sauvegarde pour désigner ma ‘/home/ricardo’ ou est-ce qu’il est préférable de faire une variable supplémentaire ?

Bonjour,

J’approuve les remarques de micky979 et de MisterFreez concernant l’utilisation du case en lieu et place du bloc “if then elsif fi”. Aux raisons déjà évoquées j’ajoute que cette structure conditionnelle est généralement destinée à vérifier des conditions plus élaborées où généralement un seul cas dépend de plusieurs variables.

Pour ta dernière demande : Je recommanderai l’emploi du ~ plutôt que le chemin réel du dossier utilisateur et ce pour une raison toute bête. Si j’ai bien compris, ton script sera à terme diffusé (c’est déjà la cas :wink:) --> tout le monde n’a pas comme dossier personnel /home/ricardo ! :laughing:

Je reviens sur cette histoire de “pense bête” : Comme tout script, il est effectivement bon de mettre un cartouche après le shebang donnant les informations suivantes :

  • l’auteur,
  • date de création
  • licence (si il y en a une)
  • objet du script (fonctionnalités)
  • pré-requis
  • paramètres en entrée / résultat

puis, à chaque correction / amélioration, compléter ce cartouche par un petit laïus daté expliquant l’objet de la nouvelle version.

mais bon, je suis peu être un peu trop formaté professionnellement :017

A voire pour la suite :

  • une option -h affichant le synopsis serait pas mal
  • plutôt que d’avoir une interaction avec l’utilisateur, ajouter des paramètres des dossiers à sauvegarder, du point de montage et de la partition à monter, suppression ou non de la corbeille, des fichiers de contrôle etc… serait nettement un plus. En effet, cela te permettrai d’ordonnancer ton script ! (rien n’empêche d’ajouter une option pour forcer l’interaction :whistle: ) Et puis, pour la même raison que pour le ~ : tout le monde n’a pas le même disque dur avec les mêmes partitions !

@+

OK pour tout mais deux zônes d’ombre :

[quote]- une option -h affichant le synopsis serait pas mal[/quote] :question: :question: :question:

[quote]- plutôt que d’avoir une interaction avec l’utilisateur, ajouter des paramètres des dossiers à sauvegarder, du point de montage et de la partition à monter, suppression ou non de la corbeille, des fichiers de contrôle etc… serait nettement un plus. En effet, cela te permettrai d’ordonnancer ton script ! (rien n’empêche d’ajouter une option pour forcer l’interaction :whistle: ) Et puis, pour la même raison que pour le ~ : tout le monde n’a pas le même disque dur avec les mêmes partitions !
[/quote]Peux-tu me donner des exemples.
Est-ce que tu parles là d’être plus explicite dans les différentes actions ?
Si oui, j’ai prévu de l’être, mais seulement quand j’aurai votre “feu vert” sur le script proprement dit :wink:
J’ai déjà répondu un peu dans ce sens à Goodluck47, quelques messages plus haut.
Il ne faut pas non plus perdre de vue que ce script n’était au départ, qu’un apprentissage, partant de zéro en matière de bash, et il n’était pas prévu qu’il puisse servir aux autres, je n’avais pas cette prétention.
Par la suite, j’ai pensé qu’il pourrait être un “plus” à mon tuto, qui lui, est suffisamment expliqué.
https://www.debian-fr.org/sauvegarde-clonage-d-une-sid-t25179.html
Une fois votre sceau appliqué, je reprendrai l’ensemble (le tuto ayant besoin de mise à jour) et j’y adjoindrai ce script, en n’omettant pas de mentionner votre participation.

re,

Plutôt d’une explication, un exemple pour tes 2 questions :

#!/bin/bash

#------------------------------------------
# Auteur : ricardo
# Date :
# Objet :
# Licence :
#------------------------------------------
# Pré-requis :
#------------------------------------------
# Paramètres :
#   Entrée :
#   Sortie/résultat :
#------------------------------------------
# Date modification :
# Version :
# Objet :
#------------------------------------------


# fonction d'affichage de l'aide
# pour info ${0##*} permet de retourner le nom du script sans l'éventuel chemin précisé
# cela évite de le mettre en "dur" au sein du script et qu'il soit désynchronisé avec le nom réel après un renommage
function help()
{
cat <<EOF
Synopsis : ${0##*/} [ -h ] [ -c ] [ -p ] [ -i ] <param1> <param2> <...> <param i>

Paramètres : 
 - -h      : Affiche cette aide
 - -c      : Suppression des dossiers de contrôle 
 - -p      : Suppression de la corbeille (p pour poubelle -- pas trouvé mieux )
 - -i      : Mode interactif
 - param1  : Dossier à sauvegarder
 - param2  : Dossier de montage
 - param3  : Partition à monter
 - ...     : ....
 - param i : explication...

Exemple :
${0##*/} -c -p /home/controle/ /dev/sdb9 /mnt/autre
EOF
}

delCont=false
delCorb=false
modInte=false
# gestion des options ...
[[ $1 == -h ]] && { help; exit; }
[[ $1 == -c ]] && { delCont=true; shift; }
[[ $1 == -p ]] && { delCorb=true; shift; }
[[ $1 == -i ]] && { modInte=true; shift; }

backupdir="$1"
ddext="$2"
autre="$3"
if ${modInte}
then
  # on est en mode interactif, on demande à l'utilisateur ce qu'il veut sauvegarder
  read -p 'sauve ou sauve2 ? : ' part    # choix de la sauvegarde
fi
...

Alors attention, la gestion des options telle que je l’indique est absolument à éviter car ce n’est aucunement fiable.
Il y a une builtin et des variables dédiées à cela : getopts et les variables OPTARG et OPTIND. Mais on en est pas là (j’approfondirai le sujet si tu le souhaites) ! Je voulais juste indiquer qu’il serait pas mal de rendre ton script autonome.

De même, les lignes de codes ne sont pas forcément représentatives de ton code.

Bien tout ça mais c’est au dessus de mes moyens intellectuels. Il me faut déjà une heure pour déchiffrer et mon pauvre neurone de 75 balais commence à chauffer.
Pour ce qui est de ce que tu appelles une “cartouche”, c’est OK et c’était prévu.
Pour le reste, je fais l’impasse, ptet temporaire ?
Merci de tes explications.

maiiiiiiiiiiiis non…
je suis persuadé que tu as jeté l’éponge un peut trop facilement :wink:

c’est fort possible !

sinon, j’ai oublié de revenir sur un point levé par micky979 : il est vrai qu’à 2 endroits il manque des tests sur le statut d’exécution. il s’agit des instructions sudo rsync ! Il n’y a rien qui indique que la synchronisation s’est bien déroulée !

Je regarde ça tout de suite mais en attendant, je te soumets une mouture améliorée avec, notamment, une “variablisation” :unamused: maximum.
J’ai intégré le ‘case…esac’ mais une seule fois. Doit-on laisser la partie “corbeille” en ‘if…fi’ ou … ?
Il ne s’agit que du code, les fioritures seront ajoutées à la fin.

[code]#!/bin/bash

ddext="/dev/sdb9"
ddext2="/dev/sdb10"
mount_rep="/mnt/autre"
systeme_fich=“ext3"
systeme_fich2=“ext2"
controle=”/home/controle"
controle_user=”/home/controle-ricardo"
exclure="/root/exclure"
exclure_user="/home/ricardo/.exclure"
sauve="/mnt/autre/sauve"
sauve_user="/mnt/autre/sauve-ricardo"

#-----------------------------------------------------------------------------

[ -e “$ddext” ] && [ -e “$ddext2” ] || { echo “Le DDext ne repond pas !” >&2; exit 1; } # teste l’existence des partitions de sauvegarde

mkdir -p “$mount_rep” || { echo “Le dossier de montage n’existe pas !” >&2; exit 1; } # teste l’existence du dossier de montage

read -p 'sauve ou sauve2 ? : ’ part # choix de la sauvegarde
case $part in
sauve)
sudo mount -t “$systeme_fich” “$ddext” “$mount_rep”
;;
sauve2)
sudo mount -t “$systeme_fich2” “$ddext2” “$mount_rep”
;;
*)
echo “mauvaise entree” >&2; exit 1;
;;
esac

echo -e "\033[4mCONTENU de la CORBEILLE\033[0m"
if [ -e ~/.local/share/Trash/files ] # teste si la corbeille est pleine (existence de /files)
then
ls ~/.local/share/Trash/files # si pleine, liste les fichiers qu’elle contient
read -p "on peut la vider ? o/* : " corbeille
if [ “$corbeille” = o ]
then
rm -rf ~/.local/share/Trash/*
echo -e "\033[4mCORBEILLE VIDEE\033[0m"
fi
else
echo "La corbeille est vide"
fi

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

sudo umount “$mount_rep”

exit
[/code]

Il s’agit d’ajouter quoi alors ?
un ‘echo’ après le ‘exit 1’, indiquant que la sauvegarde n’a pa été effectuée ?
Micky avait parlé d’une explication au ‘exit 1’ mais je ne sais pas comment écrire ça.

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

[quote=“ricardo”]Il s’agit d’ajouter quoi alors ?
un ‘echo’ après le ‘exit 1’, indiquant que la sauvegarde n’a pa été effectuée ?[/quote]Si tu ajoutes un echo, ajoutes-le avant le exit sinon je pense que tu n’en verras jamais l’éxecution.

EDIT de Ricardo :
:blush: :blush: :blush:
Bien sûr, c’est comme ça que je le voyais :006

Une instruction/commande (pipeline) se termine en fournissant une information sur son bon déroulement. C’est le statut (0=tout est ok, >0=une erreur). La valeur de ce statut est celle que l’on donne au exit. Il peut être testé de 2 façons :

(à noter que toute commande est une pipeline - qu’il y ait ou non un pipe)

1 - en testant directement la pipeline

if sudo rsync ... 
then 
  echo "Sauvegarde du dossier /home/ricardo ok"
else
  echo "Erreur lors de la sauvegarde" >&2
  exit 1
fi

# ou bien (en inversant la valeur du statut avec le !)
if ! sudo rsync ...
then 
  echo "Erreur lors de la sauvegarde" >&2
  exit 1
fi
echo "Sauvegarde du dossier /home/ricardo ok"

# ou encore 
! sudo rsync ... && { echo "Erreur lors de la sauvegarde" >&2; exit 1; }
echo "Sauvegarde du dossier /home/ricardo ok"

# enfin
sudo rsync ... || { echo "Erreur lors de la sauvegarde" >&2; exit 1; }
echo "Sauvegarde du dossier /home/ricardo ok"

2 - En exploitant la variable $? qui contient le statut de la dernière pipeline exécutée :

sudo rsync ...
if (( $? == 0 )) 
  echo "Sauvegarde du dossier /home/ricardo ok"
else
  echo "Erreur lors de la sauvegarde" >&2
  exit 1
fi

# ou bien
sudo rsync ...
if (( $? > 0 ))
then 
  echo "Erreur lors de la sauvegarde" >&2
  exit 1
fi
echo "Sauvegarde du dossier /home/ricardo ok"

# ou encore
sudo rsync ...
(( $? > 0 )) && { echo "Erreur lors de la sauvegarde" >&2; exit 1; }
echo "Sauvegarde du dossier /home/ricardo ok"

Ah bon ! je pensais que c’était une commande spéciale mais là, je sais faire, c’est un simple if … fi pour informer.
Ok, je vais ajouter.

EDIT :
Comme il y a deux sauvegardes différentes, je pense que je dois placer deux fois l’information ?

sudo rsync -av --del --backup --backup-dir="$controle" --exclude-from="$exclure" / "$sauve" sudo rsync -av --del --backup --backup-dir="$controle_user" --exclude-from="$exclure_user" ~/ "$sauve_user"

Verdict ?

[code]#!/bin/bash

ddext="/dev/sdb9"
ddext2="/dev/sdb10"
mount_rep="/mnt/autre"
systeme_fich=“ext3"
systeme_fich2=“ext2"
controle=”/home/controle"
controle_user=”/home/controle-ricardo"
exclure="/root/exclure"
exclure_user="/home/ricardo/.exclure"
sauve="/mnt/autre/sauve"
sauve_user="/mnt/autre/sauve-ricardo"

#-----------------------------------------------------------------------------

[ -e “$ddext” ] && [ -e “$ddext2” ] || { echo “Le DDext ne repond pas !” >&2; exit 1; } # teste l’existence des partitions de sauvegarde

mkdir -p “$mount_rep” || { echo “Le dossier de montage n’existe pas !” >&2; exit 1; } # teste l’existence du dossier de montage

read -p 'sauve ou sauve2 ? : ’ part # choix de la sauvegarde
case $part in
sauve)
sudo mount -t “$systeme_fich” “$ddext” “$mount_rep”
;;
sauve2)
sudo mount -t “$systeme_fich2” “$ddext2” “$mount_rep”
;;
*)
echo “mauvaise entree” >&2; exit 1;
;;
esac

echo -e "\033[4mCONTENU de la CORBEILLE\033[0m\n"
if [ -e ~/.local/share/Trash/files ] # teste si la corbeille est pleine (existence de /files)
then
ls ~/.local/share/Trash/files # si pleine, liste les fichiers qu’elle contient
read -p "on peut la vider ? o/* : " corbeille
if [ “$corbeille” = o ]
then
rm -rf ~/.local/share/Trash/*
echo -e "\033[4mCORBEILLE VIDEE\033[0m"
fi
else
echo "La corbeille est vide"
fi

read -p “prêt pour la sauvegarde ? o/* : " onyva
if [ “$onyva” = o ]
then
sudo rsync -av --del --backup --backup-dir=”$controle" --exclude-from="$exclure" / “$sauve"
if (( $? == 0 ))
then
echo -e “\nSauvegarde de / : ok\n"
else
echo -e “\nErreur lors de la sauvegarde de /\n” >&2
exit 1
fi
sudo rsync -av --del --backup --backup-dir=”$controle_user” --exclude-from="$exclure_user" ~/ "$sauve_user"
if (( $? == 0 ))
then
echo -e "\nSauvegarde du dossier /home/user : ok\n"
else
echo -e “\nErreur lors de la sauvegarde de /home/user\n” >&2
exit 1
fi
else
exit 1
fi

sudo umount “$mount_rep”

exit
[/code]

Oui, c’est ça :wink:

bon, 3 remarques :

  • c’est dommage de mettre /home/user et non pas le vrai nom de dossier
  • plutôt que d’utiliser echo -e, il est d’habitude d’utiliser sa grande soeur printf
  • tu ne trouves pas que c’est un peu redondant tes 2 if après la sauvegarde et qu’à quelque chose près c’est kifkif bourricot ? ça serait pas mieux de mutualiser avec une fonction ?

[quote=“Totor”]Oui, c’est ça :wink:

  • c’est dommage de mettre /home/user et non pas le vrai nom de dossier[/quote] On me dit toujours de privilégier la “portabilité”, alors j’obéis. Si je mets /home/ricardo, celui qui voudra reprendre le script devra le modifier, tandis que là, c’est international, je n’ai même pas écrit “utilisateur” :smiley:

[quote=“Totor”]- plutôt que d’utiliser echo -e, il est d’habitude d’utiliser sa grande soeur printf [/quote]OK, je fais. Je suppose que c’est pour éviter le ‘-e’, c’est ça ?

[quote=“Totor”]- tu ne trouves pas que c’est un peu redondant tes 2 if après la sauvegarde et qu’à quelque chose près c’est kifkif bourricot ? ça serait pas mieux de mutualiser avec une fonction ?[/quote]J’aurais pu n’en placer qu’un pour les deux lignes mais ça me semblait illogique car la première peut “passer”, tandis que la seconde peut foirer. Tu veux bien me faire un croquis de fonction qui irait bien, merci.

ben justement mettre printf “\nSauvegarde du dossier %s\n” ~/
ça marche à tous les coups et ça donne le dossier réel :wink:

tout à fait.

function testSauvegarde()
{
<le code qui va bien>
}

note : au sein du fonction, on récupère les paramètres avec les “paramètres” positionnels. i.e $1, $2, $3 … etc…
ces paramètres sont passés à la fonction de la même façon que pour toute commande (exemple --> ton rsync)

[quote]note : au sein du fonction, on récupère les paramètres avec les “paramètres” positionnels. i.e $1, $2, $3 … etc…
ces paramètres sont passés à la fonction de la même façon que pour toute commande (exemple --> ton rsync)[/quote]
Excuse-moi mais là, c’est du Mandarin pour moi :confused:

EDIT :
J’ai trouvé un exemple qui pourrait me guider mais je ne comprends pas une donnée (en rouge) à quoi correspond l’arobase

[quote]E_MAUVAISREP=65

var=repertoire_inexistant

error()
{
printf “$@” >&2

Formate les paramètres de position passés et les envoie vers stderr.

echo
exit $E_MAUVAISREP
}

cd $var || error $“Ne peut aller dans %s.” “$var”

Merci, S.C.

[/quote]

EDIT 2 :
J’ai vu qu’il s’agissait d’un paramètre de position.

[quote=“ricardo”]On me dit toujours de privilégier la “portabilité”, alors j’obéis. Si je mets /home/ricardo, celui qui voudra reprendre le script devra le modifier, tandis que là, c’est international, je n’ai même pas écrit “utilisateur”.[/quote]Avec /home/user aussi il faudra modifier, si tu mettais $HOMEpas besoin.

Oui, ou comme m’a indiqué Totor :
printf “\nSauvegarde du dossier %s\n” ~/
qui va très bien.

[quote=“Totor”]note : au sein du fonction, on récupère les paramètres avec les “paramètres” positionnels. i.e $1, $2, $3 … etc…
ces paramètres sont passés à la fonction de la même façon que pour toute commande (exemple --> ton rsync)[/quote]
Bon, j’ai eu beau chercher, je pédale dans la semoule, je ne percute pas sur ce que tu proposes :confused: