#1 Le 27/01/2014, à 21:45
- Tartampion91
[Script/bash] sauvegarde / restaure
Bonjour a tous,
Je vous poste ici un script que j'ai développé qui sauvegarde le contenu d'un répertoire dans une archive tar.gz et la déplace dans un répertoire.
Je sais qu'il existe déjà plusieurs logiciel qui font cela très bien, le but étais de m'exercer au développement en shell et a la manipulation des archives tar.
C'est un de mes premier shell, donc il est loin d'être parfait.
#!/bin/bash
#---------------------------------------------------------------
# AUTEUR : Jerome MARTIN
# DATE : 01 septembre 2013
# DESCRIPTION : Savegarde les données contenu dans un dossier et
# déplace l'achive créée dans un dossier spécifique
# en conservant les droits sur les fichiers
# PARAMETRE : Aucun
#---------------------------------------------------------------
#--------------------------------------------------------------------
# FONCTION Question
# Pose une question à laquelle il faut répondre par Oui / Non
#
# PARAMETRES
# $1 : QUESTION : Nom de l'archive à extraire
# $2 : DEFAUT : Valeur par défaut
#
# RETOURNE
# 1 : Si la réponse est OUI
# 0 : Si la réponse est NON
#----------------------------------------------------------------------
function Question
{
QUESTION="$1"
DEFAUT="$2"
while :
do
sleep 1
printf "\n${QUESTION} [${DEFAUT}] "
read REPONSE
case "${REPONSE}" in
[OoYy1]*)
REPONSE=1
break
;;
[Nn0]*)
REPONSE=0
break
;;
'')
case "${DEFAUT}" in
[OoYy1]*)
REPONSE=1
break
;;
[Nn0]*)
REPONSE=0
break
;;
esac
esac
printf 'Merci de repondre "O" pour Oui ou "N" pour Non.'
done
}
#---------------------------------------------------------------------------
# NOM : Sauvegarde
# Description : Sauvegarde le contenu d'un repertoir dans une archive tar.gz
# Retourne : Rien
#----------------------------------------------------------------------------
function Sauvegarde
{
printf "Entrer le repertoir a sauvegarder : " | tee -a $LOG
read REP_SAVE
printf "Entrer le repertoir de destination de l'archive : " | tee -a $LOG
read REP_DEST
if [ ! -d $REP_SAVE ]
then
printf "Le repertoir a sauvegarder n'existe pas\n" | tee -a $LOG
exit 11
fi
if [ ! -d $REP_DEST ]
then
printf "Le repertoir d'archivage n'existe pas\n" | tee -a $LOG
exit 12
fi
printf "Vous allez sauvegarder le contenu de $REP_SAVE, l'archive créer sera placer dans $REP_DEST\n"
Question "Voulez-vous continuer ?" "o"
if [ $REPONSE -eq 0 ]
then
printf "Abandon par l'utilisateur !\n" | tee -a $LOG
exit 19
fi
cd /
printf "Creation de l'archive tar ... " | tee -a $LOG
DOSSIER=`echo $REP_SAVE | awk 'BEGIN { FS="/" } { print $NF }'`
tar -czf "save_${DOSSIER}_${DATE_DU_JOUR}.tgz" $REP_SAVE* >> $LOG
RC=$?
if [ $RC != 0 ]
then
printf "KO\n"
printf "Echec de la creation de l'archive, erreur : $RC\n" | tee -a $LOG
exit 1
else
printf "OK\n" | tee -a $LOG
fi
printf "Déplacement de l'archive vers $REP_DEST... " | tee -a $LOG
mv save_${DOSSIER}_${DATE_DU_JOUR}.tgz $REP_DEST
RC=$?
if [ $RC != 0 ]
then
printf "KO\n"
printf "Echec du déplacement de l'archive, erreur : $RC\n" | tee -a $LOG
exit 4
else
printf "OK\n" | tee -a $LOG
fi
printf "Appuyer sur Entrer pour continuer"
read touche
}
#---------------------------------------------------------------------------
# NOM : restore_fichier
# Description : restaure un fichier d'une archive tar.gz
# Retourne : Rien
#----------------------------------------------------------------------------
function restore_fichier
{
printf "Entrer le fichier a restaurer : " | tee -a $LOG
read NOM_FICHIER
echo
printf "Entrer la date de l'archive a selectionner ( JJ-MM-AAAA ) : " | tee -a $LOG
read DATE_ARCHIVE
FICHIER_ZIP=`find / -name *$DATE_ARCHIVE*.gz`
if [ -z $FICHIER_ZIP ]
then
printf "Archvive non trouver\n" | tee -a $LOG
exit 6
fi
printf "Decompression de l'archive... " | tee -a $LOG
#FICHIER_ZIP=`ls *$DATE_ARCHIVE*.tar.gz`
gunzip $FICHIER_ZIP
RC=$?
if [ $RC != 0 ]
then
printf "KO\nEchec de la decompression, code erreur : $RC" | tee -a $LOG
exit 5
else
printf "OK\n" | tee -a $LOG
fi
FICHIER_TAR=`echo $FICHIER_ZIP | sed s/.gz//g`
printf "recherche du fichier : $NOM_FICHIER dans $FICHIER_TAR ... " | tee -a $LOG
OLD_IFS=$IFS
IFS="
"
LISTE_FICHIER_TAR=`tar -tvf $FICHIER_TAR`
FLAG=0
cd /
for FICHIER in $LISTE_FICHIER_TAR
do
#echo "$FICHIER == $NOM_FICHIER" >> $LOG
if [[ "$FICHIER" =~ (.*)$NOM_FICHIER(.*) ]]
then
FICHIER_EXTRACT=`echo $FICHIER | awk '{ print $6 }'`
#printf "tar --extract --file=$FICHIER_TAR $FICHIER_EXTRACT\n"| tee -a $LOG
tar --extract --file=$FICHIER_TAR $FICHIER_EXTRACT
RC=$?
if [ $RC != 0 ]
then
printf "KO\nEchec de la restauration du fichier, code erreur tar : $RC\n" | tee -a $LOG
printf "Compression de l'archive.."
gzip $FICHIER_TAR
RC=$?
if [ $RC != 0 ]
then
printf "KO\nEchec de la compression de l'archive, code erreur : $RC\n" | tee -a $LOG
exit 10
else
printf "OK\n" | tee -a $LOG
fi
exit 7
else
printf "OK\n" | tee -a $LOG
FLAG=1
fi
fi
done
IFS=$OLD_IFS
if [ $FLAG != 1 ]
then
printf "KO\n" | tee -a $LOG
printf "Fichier non trouver dans l'archive $FICHIER_TAR\n" | tee -a $LOG
else
printf "Fichier restaurer !\n" | tee -a $LOG
fi
printf "Compression de l'archive ... " | tee -a $LOG
gzip $FICHIER_TAR
RC=$?
if [ $RC != 0 ]
then
printf "KO\nEchec de la compression de l'archive, code erreur : $RC" | tee -a $LOG
exit 10
else
printf "OK\n" | tee -a $LOG
fi
printf "Appuyer sur Entrer pour continuer"
read touche
}
#---------------------------------------------------------------------------
# NOM : restore_archive
# Description : restaure une archive tar.gz
# Retourne : Rien
#----------------------------------------------------------------------------
function restore_archive
{
printf "Entrer la date de l'archive a restaurer : " | tee -a $LOG
read DATE_ARCHIVE
FICHIER_ZIP=`find / -name *$DATE_ARCHIVE*.gz`
NB_ARCHIVE=`echo $FICHIER_ZIP | wc -l`
if [ $NB_ARCHIVE -gt 1 ]
then
printf "Plusieurs archives trouvees a cette date\n" | tee -a $LOG
printf "Liste des archives trouvees : \n" | tee -a $LOG
echo $FICHIER_ZIP
printf "Entrer le nom complet de l'achive a restaurer : \n" | tee -a $LOG
read NOM_ARCHIVE
FICHIER_ZIP=`find / -name *$NOM_ARCHIVE*`
fi
printf "Vous allez restaurer l'archive $FICHIER_ZIP\n"
Question "Voulez-vous continuer ?" "o"
if [ $REPONSE -eq 0 ]
then
printf "Abandon par l'utilisateur !\n" | tee -a $LOG
exit 20
fi
cd /
printf "Restauration en cours... " | tee -a $LOG
tar -xzf $FICHIER_ZIP
RC=$?
if [ $RC != 0 ]
then
printf "KO\n"
printf "Erreur lors de la restauration de l'archive, tar retourne l'erreur : $RC\n" | tee -a $LOG
exit 19
fi
printf "OK\n" | tee -a $LOG
printf "Appuyer sur Entrer pour continuer"
read touche
}
#---------------------------------------------------------------
# MAIN
#---------------------------------------------------------------
DATE_DU_JOUR=`date +%d-%m-%Y`
HEURE=`date +%H%M%S`
LOG="/tmp/save_${DATE_DU_JOUR}.log"
#Redirection de la sortie d'erreur
exec 2>$LOG
#Verification du USER
USER=`whoami`
if [ $USER != "root" ]
then
printf "$USER : utilisateur interdit\n" | tee -a $LOG
printf "Merci de vous connecter en root\n" | tee -a $LOG
exit 3
fi
while ((1))
do
clear
printf "***********************************************\n"
printf "* Menu sauvegarde / restaure \n"
printf "* \n"
printf "* 1 - Sauvegarde \n"
printf "* \n"
printf "* 2 - Restaure fichiers \n"
printf "* \n"
printf "* 3 - Restaure archive \n"
printf "* \n"
printf "* 4 - Quitter \n"
printf "* \n"
printf "***********************************************\n"
printf "Entrez le chiffre correspondant a votre choix : " | tee -a $LOG
read REPONSE
case "${REPONSE}" in
[1]*)
Sauvegarde
REPONSE=1
;;
[2]*)
restore_fichier
REPONSE=0
;;
[3]*)
restore_archive
REPONSE=2
;;
[4]*)
break
;;
esac
printf "Merci de repondre "1", "2", "3" ou "4"."
done
fi
Toute amélioration est bonne à prendre alors n'hésitez pas
A+
Hors ligne
#2 Le 28/01/2014, à 08:58
- pingouinux
Re : [Script/bash] sauvegarde / restaure
Bonjour,
Voici quelques remarques après avoir lu ton script en diagonale.
Ligne 81
if [ ! -d $REP_SAVE ]
Mettre des " " autour des variables (utile si elles contiennent des espaces)
if [ ! -d "$REP_SAVE" ]
Ligne 106
DOSSIER=`echo $REP_SAVE | awk 'BEGIN { FS="/" } { print $NF }'`
peut être remplacée par
DOSSIER=${REP_SAVE##*/}
Lignes 107 à 116
tar -czf "save_${DOSSIER}_${DATE_DU_JOUR}.tgz" $REP_SAVE* >> $LOG
RC=$?
if [ $RC != 0 ]
then
printf "KO\n"
printf "Echec de la creation de l'archive, erreur : $RC\n" | tee -a $LOG
exit 1
else
printf "OK\n" | tee -a $LOG
fi
peuvent être remplacées par
if tar -czf "save_${DOSSIER}_${DATE_DU_JOUR}.tgz" "$REP_SAVE" >> "$LOG"
then
printf "OK\n" | tee -a $LOG
else
printf "KO\n"
printf "Echec de la creation de l'archive, erreur : $RC\n" | tee -a "$LOG"
exit 1
fi
(guillemets ajoutés autour de $REP_SAVE et $LOG; à quoi sert l'astérisque ?; utilisation de la variable RC inutile, sauf si tu veux voir sa valeur en cas d 'erreur)
Dernière modification par pingouinux (Le 28/01/2014, à 09:07)
Hors ligne
#3 Le 28/01/2014, à 14:14
- Tartampion91
Re : [Script/bash] sauvegarde / restaure
Bonjour pingouinux,
Merci d'avoir pris le temps de me répondre.
Je vais suivre tes conseils, effectivement la variable RC est la pour voir sa valeur en cas d'erreur.
J'aimerai également ajouter à ce script un test sur l'espace disque du répertoire de destination de l'archive afin d'être sur qu'il y est bien la place de stocker l'achive.
As-tu une idées de comment je pourrais faire ?
Hors ligne
#4 Le 28/01/2014, à 14:39
- pingouinux
Re : [Script/bash] sauvegarde / restaure
taille_archive=$(stat -c "%s" archive.tgz)
taille_destination=$(df -B1 repertoire_destination | awk 'NR==2{print $4}')
Hors ligne
#5 Le 28/01/2014, à 14:46
- Arbiel
Re : [Script/bash] sauvegarde / restaure
Tu peux aussi utiliser zenity ou YAD (que je n'ai encore jamais utilisé moi-même) pour la gestion des dialogues.
Dernière modification par Arbiel (Le 28/01/2014, à 14:54)
Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04, GNOME 3.36.8
24.04 en cours de tests
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.
Hors ligne
#6 Le 29/01/2014, à 15:13
- moths-art
Re : [Script/bash] sauvegarde / restaure
Je sais qu'il existe déjà plusieurs logiciel qui font cela très bien...
En fait, pas vraiment
En terme de backup, je trouve justement qu'il n'existe pas vraiment de soft qui sorte du lot et que les besoins ad-hock oblige à faire du "homemade" un jour ou l'autre si on veut pas quelque chose de bancal.
Petite suggestion de poursuite.
Si l'archive est volumineuse, tu peux utiliser du .dar : c'est le remplaçant du tar mais fragmenté... ça évite des tar de plusieurs Giga/Terra.
Egalement : renseigne toi sur Rsync : ça évite de manipuler tous les fichiers mais seulement ceux qui ont été modifiés.
Enfin : je te conseil d'utiliser Brebis : http://brebisproject.org/
C'est un soft qui s'assure de l'intégrité de tes sauvegardes... et ça, ça n'a pas de prix.
Site : https://mothsart.github.io Dépôts Git : https://github.com/mothsart PPAs : https://launchpad.net/~jerem-ferry
Hors ligne
#7 Le 30/01/2014, à 18:07
- Tartampion91
Re : [Script/bash] sauvegarde / restaure
Merci pour vos réponse
Je vais me renseigner pour les archives en .dar car c'est vrai que les archives atteigne vite plusieurs giga ( surtout les répertoire utilisateur )
Pour ce qui est de la sauvegarde incrémentale je comptais le faire mais avec la commande : find répertoir_à_sauvegarder -newer
Enfin je compte aussi mettre des options à mon script afin de pouvoir le lancer via un crontab
Il me reste pas mal de boulot donc rester dans le coin j'aurais surement encore besoin de vous vu le novice que je suis =P
A+
Hors ligne