Script sauvegarde

Description

sauvegarde a pour but de permettre un meilleur contrôle du logiciel de synchronisation rsync, dans le cadre de sauvegardes automatisées. Il peut utiliser un fichier de configuration pour chaque type de sauvegarde, fichier qu'il peut créer sur demande.

Téléchargement

Télécharger sauvegarde

sauvegarde est distribué sous licence libre CeCILL.

Installation

Une fois le fichier téléchargé, vous devez

Ce logiciel nécessite l'utilisation de l'utilitaire rsync, installable sous Ubuntu ou Debian par

sudo aptitude install rsync

Utilisation

Même si ce n'est pas obligatoire, le mieux est ensuite de créer un fichier de configuration, par exemple ~/.sauvegarde-documents

sauvegarde creer .sauvegarde-documents

qu'il faudra ensuite modifier à la main.

Enfin, il est conseillé lors du premier lancement d'utiliser l'option -n, qui prévient de toute action. Sauf si l'option -v ou VERBOSE est activée, la sortie du logiciel rsync est envoyée dans un fichier .rsync.log dans le répertoire synchronisé.

Dans la pratique, on pourra donc utiliser simplement la ligne, suivie ou non de l'option -n 

sauvegarde CONF=~/.sauvegarde-documents

Je vous conseille de mettre ça dans une crontab pour le déclencher tous les jours...

Aide en ligne

$ sauvegarde -h

Usage : sauvegarde [CONF=config] [-vsnzd] [HOST=hôte] [LOGIN=login]
               [REPL=rép_local] [REPD=rép_distant] [EXCL=exclusions] [options]
        sauvegarde creer [CONF=]config
        sauvegarde -h

Effectue une sauvegarde du répertoire local rép_local sur hôte à l'intérieur du
répertoire rép_distant, connecté en tant que connecté en tant que login.

Les chemins aux répertoires peuvent être relatifs ou absolus.
Le fichier de configuration config peut être précisé. Les valeurs contenues
dans config sont prioritaires sur celles définies par défaut, mais non sur
celles entrées en ligne.
Les exclusions sont des chaines de caractères sans espace, avec joker éventuel.
Des chaines multiples peuvent être séparées par le caractère ":". Elles sont
sensibles à la casse. Tout répertoire ou fichier dont le nom contient une de ces
chaines sera exclus.
Des options peuvent éventuellement être passées au logiciel rsync utilisé.
Si la commande creer est invoquée, un fichier de configuration typique sera créé
à l'emplacement config. Il faudra ensuite le modifier à la main.

Options :
 -h : afficher cette aide
 -v : mode verbeux, désactive l'enregistrement des actions dans
      rép_local/.rsync.log et les affiche dans la sortie standard
 -s : utiliser localement sudo pour résoudre les problèmes de droits de lecture
 -n : mode sans transfert ('dry-run'), liste seulement les actions à effectuer
 -z : compression des données pendant l'échange
 -d : ne pas détruire sur hôte les fichiers qui n'existent plus localement

Valeurs actuelles par défaut :
HOST : hote
LOGIN : login
REPL : home
REPD : .
EXCL : cache:Cache:.thumbnails:.lock:_lock:.Trash:.gvfs

Transcript

#!/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, <ravat@free.fr> (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"