Contenu | Rechercher | Menus

Annonce

Si vous rencontrez des soucis à rester connecté sur le forum (ou si vous avez perdu votre mot de passe) déconnectez-vous et reconnectez-vous depuis cette page, en cochant la case "Me connecter automatiquement lors de mes prochaines visites".
Test de l'ISO d'Ubuntu francophone : nous avons besoin de testeurs pour la version francophone d'Ubuntu 14.04. Liens et informations ici.

#1 Le 27/01/2014, à 22: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 wink

A+

Hors ligne

#2 Le 28/01/2014, à 09: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, à 10:07)

Hors ligne

#3 Le 28/01/2014, à 15: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, à 15: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, à 15: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, à 15:54)


Arbiel Perlacremaz
Dell Vostro 3550 Ubuntu 14.04 64 bits

Hors ligne

#6 Le 29/01/2014, à 16:13

moths-art

Re : [Script/bash] sauvegarde / restaure

Tartampion91 a écrit :

Je sais qu'il existe déjà plusieurs logiciel qui font cela très bien...

En fait, pas vraiment wink
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.

Hors ligne

#7 Le 30/01/2014, à 19:07

Tartampion91

Re : [Script/bash] sauvegarde / restaure

Merci pour vos réponse smile

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

Haut de page ↑