#!/bin/bash # This software is governed by the CeCILL license under French law and # abiding by the rules of distribution of free software. You can use, # modify and/ or redistribute the software under the terms of the CeCILL # license as circulated by CEA, CNRS and INRIA at the following URL # "http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt". # # Ce logiciel est régi par la licence CeCILL soumise au droit français et # respectant les principes de diffusion des logiciels libres. Vous pouvez # utiliser, modifier et/ou redistribuer ce programme sous les conditions # de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA # à l'adresse "http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt". # # Copyright Cyril Ravat, (2007-2010) # Website : http://www.cyril-ravat.fr/scripts/sauvegarde.php # Help : sauvegarde -h ##################### ### Configuration ### ##################### # Login sur l'hôte par défaut LOGIN=login # Répertoire local à sauvegarder par défaut REPL=home # Répertoire distant ou sauvegarder par défaut REPD="." # Hôte par défaut HOST=hote # Définition de l'hôte selon l'endroit où on est. # Couples [IP,hôte] : IH=(ip1 hôte1 ip2 hôte2 ... ) # Ces valeurs sont utilisées en priorité sur HOST : HOST est la l'hôte # déterminé au final si l'IP n'est aucune de celles renseignées dans IH. # L'IP est déterminée grâce à http://checkip.dyndns.org (IP non locale) #IH=(ip_maison hote_local) # Fichiers/répertoires à exclure (option --exclude de rsync) EXCL="cache:Cache:.thumbnails:.lock:_lock:.Trash:.gvfs" # Mode verbeux #VERBOSE=1 # Utilisation du sudo #SUDO=sudo # Mode sans destruction #NODELETE=1 # Options rsync #OPTS= ############################### ### Fin de la configuration ### ############################### # Fichier de configuration éventuel if [ "${1:0:4}" = "CONF" ]; then [ -e "${1:5}" ] && source "${1:5}" shift # Demande de création d'un fichier de configuration elif [ "$1" = "creer" ]; then [ "${2:0:4}" = "CONF" ] && FICHIER="${2:5}" || FICHIER="$2" # Vérifier les droits d'écriture if [ ! -w $(dirname "$FICHIER") ] && [ ! -w "$FICHIER" ]; then echo -e "Il est impossible d'écrire dans le fichier \033[1m$FICHIER\033[0m." echo "Modifier vos droits d'écriture devrait résoudre ce problème." exit 1 fi # Vérifier si le fichier existe, demander confimation if [ -e "$FICHIER" ]; then read -p "Le fichier existe déjà. Voulez-vous l'écraser ? [o/N] " ok if [ -z "$ok" ] || [ `expr "$ok" : '[oOyY]'` == 0 ]; then echo "Aucune modification n'a été effectuée." exit 0 fi fi # Écrire dans le fichier la configuration de base sed -n '/^### Configuration/,/^### Fin de la configuration /p' "$0" | sed '1,3d;$d' | sed '$d' > "$FICHIER" echo -e "Vous pouvez éditer maintenant le fichier de configuration \033[1m$FICHIER\033[0m." exit 0 fi # Options du script while getopts ":hvsnzd" option do case $option in "h") echo -e "Usage : $(basename "$0") [CONF=\033[1mconfig\033[0m] [-vsnzd] [HOST=\033[1mhôte\033[0m] [LOGIN=\033[1mlogin\033[0m]" echo -e " [REPL=\033[1mrép_local\033[0m] [REPD=\033[1mrép_distant\033[0m] [EXCL=\033[1mexclusions\033[0m] [\033[1moptions\033[0m]" echo -e " $(basename "$0") creer [CONF=]\033[1mconfig\033[0m" echo " $(basename "$0") -h" echo echo -e "Effectue une sauvegarde du répertoire local \033[1mrép_local\033[0m sur \033[1mhôte\033[0m à l'intérieur du" echo -e "répertoire \033[1mrép_distant\033[0m, connecté en tant que connecté en tant que \033[1mlogin\033[0m." echo echo -e "Les chemins aux répertoires peuvent être relatifs ou absolus." echo -e "Le fichier de configuration \033[1mconfig\033[0m peut être précisé. Les valeurs contenues" echo -e "dans \033[1mconfig\033[0m sont prioritaires sur celles définies par défaut, mais non sur" echo -e "celles entrées en ligne." echo -e "Les \033[1mexclusions\033[0m sont des chaines de caractères sans espace, avec joker éventuel." echo -e "Des chaines multiples peuvent être séparées par le caractère \":\". Elles sont" echo -e "sensibles à la casse. Tout répertoire ou fichier dont le nom contient une de ces" echo -e "chaines sera exclus." echo -e "Des \033[1moptions\033[0m peuvent éventuellement être passées au logiciel rsync utilisé." echo -e "Si la commande \033[1mcreer\033[0m est invoquée, un fichier de configuration typique sera créé" echo -e "à l'emplacement \033[1mconfig\033[0m. Il faudra ensuite le modifier à la main." echo echo "Options :" echo -e " \033[1m-h\033[0m : afficher cette aide" echo -e " \033[1m-v\033[0m : mode verbeux, désactive l'enregistrement des actions dans" echo -e " \033[1mrép_local\033[0m/.rsync.log et les affiche dans la sortie standard" echo -e " \033[1m-s\033[0m : utiliser localement sudo pour résoudre les problèmes de droits de lecture" echo -e " \033[1m-n\033[0m : mode sans transfert ('dry-run'), liste seulement les actions à effectuer" echo -e " \033[1m-z\033[0m : compression des données pendant l'échange" echo -e " \033[1m-d\033[0m : ne pas détruire sur \033[1mhôte\033[0m les fichiers qui n'existent plus localement" echo echo "Valeurs actuelles par défaut :" echo -e "\033[1mHOST\033[0m : $HOST" echo -e "\033[1mLOGIN\033[0m : $LOGIN" echo -e "\033[1mREPL\033[0m : $REPL" echo -e "\033[1mREPD\033[0m : $REPD" echo -e "\033[1mEXCL\033[0m : $EXCL" exit 0 ;; "v") VERBOSE=1 ;; "s") SUDO=sudo ;; "n") OPT="n" ;; "z") OPT="${OPT}z" ;; "d") NODELETE=1 ;; "?") break ;; esac done # Autres options while [ -n "$1" ]; do case "$1" in -*) [ `expr "${1:1:1}" : '[vsnzd]'` == 1 ] && shift || break ;; CONF=*) [ -e "${1:5}" ] && source "${1:5}" ; shift ;; HOST=*) HOST="${1:5}" ; HOST_FORCE=1 ; shift ;; LOGIN=*) LOGIN="${1:6}" ; shift ;; REPL=*) REPL="${1:5}" ; shift ;; REPD=*) REPD="${1:5}" ; shift ;; EXCL=*) EXCL="${1:5}" ; shift ;; * ) break ;; esac done # Vérification de l'utilitaire rsync if [ -z `which rsync` ]; then echo -e "L'utilitaire \033[1mrsync\033[0m n'existe pas." echo -e "Il faut installer le paquet du même nom." exit 1 fi # Vérification de l'existence du répertoire local à sauvegarder if [ ! -d "$REPL" ]; then echo -e "Le répertoire \033[1m$REPL\033[0m n'existe pas." echo "Aucune action n'a été effectuée." exit 1 fi # Hôte if [ -n "$IH" ] && [ ! -n "$HOST_FORCE" ]; then IP=`wget http://checkip.dyndns.org -qO- | sed -e 's/.* //' -e 's/<.*//'`; [ -z "$IP" ] && echo "Aucune connexion n'est établie, sauvegarde impossible." && exit 1 C=0 while [ -n "${IH[$C]}" ]; do [ "$IP" = "${IH[$C]}" ] && HOST="${IH[$C+1]}" && break let C+=2 done fi # Vérifier la connexion [ -z "`ping -c 1 -W 5 -q $HOST 2>/dev/null | sed -n 's/^.*\(1 received\).*$/\1/p'`" ] \ && echo -e "L'hôte \033[1m$HOST\033[0m ne répond pas, la sauvegarde est impossible." && exit 1 # Options rsync OPTS="-auhi$OPT --inplace --copy-unsafe-links --ignore-errors $OPTS" [ $VERBOSE ] && OPTS="$OPTS --progress" [ $NODELETE ] || OPTS="$OPTS --delete --delete-excluded" [ -n "$1" ] && OPTS="$OPTS $*" # Transformation des exclusions if [ -n "$EXCL" ]; then IFS=':' for ITEM in $EXCL; do EXCL_OPT="$EXCL_OPT --exclude=$ITEM" done IFS=' ' fi # Placement dans le répertoire OLDREP="$PWD" cd "$REPL" # Si on n'a pas changé de répertoire, problème de droits if [ "$OLDREP" == "$PWD" ] && [ "$REPL" != "$OLDREP" ]; then echo -e "Problème de droits : accès non autorisé au répertoire \033[1m$REPL\033[0m" if [ -z $VERBOSE ]; then # On demande si on peut accorder le droit d'exécution du répertoire, pour pouvoir écrire dans .rsync.log echo -e "Cela va poser un problème pour écrire dans le fichier \033[1m.rsync.log\033[0m." read -p "Peut-on rajouter les droits d'exécution au répertoire (chmod o+x) ? [o/N] " ok if [ -n "$ok" ] && [ `expr "$ok" : '[oOyY]'` == 1 ]; then $SUDO chmod o+x "$REPL" else echo "Mode verbeux activé" VERBOSE=1 fi fi fi # Si mode non verbeux, sauvegarde du fichier de log # puis redirection de la sortie (avec enregistrement de son existance dans la sortie 9 if [ -z $VERBOSE ]; then [ -e "$REPL/.rsync.log" ] && $SUDO mv "$REPL/.rsync.log" "$REPL/.rsync.log.bak" $SUDO touch "$REPL/.rsync.log" $SUDO chmod 777 "$REPL/.rsync.log" exec 9<&1 1>"$REPL/.rsync.log" fi # Début des informations : précédente sauvegarde et début du transfert cat "$REPL/.rsync.log" "$REPL/.rsync.log.bak" 2>/dev/null | sed -n '3 s/.* le /Précédente sauvegarde le /p' echo "-------------------" echo -n "Début de sauvegarde le" date '+ %A %d %B %Y à %T' echo # Transfert $SUDO rsync $OPTS$EXCL_OPT "$REPL/" $LOGIN@$HOST:"\"$REPD\"" # Fin des informations echo -ne "\nFin du transfert à" date '+ %T' echo "-------------------" # Rétablissement de la sortie standard et transfert du fichier de log if [ -z $VERBOSE ]; then exec 1<&9 9<&- $SUDO rsync $OPTS "$REPL/.rsync.log" $LOGIN@$HOST:"\"$REPD\"" >> /dev/null fi cd "$OLDREP"