Voila mon petit script destiné à touner une fois par jour afin de tenir à jour la sauvegarde de mon /home sur un disque dur accessible sur le réseau via le protocole NFS. Ca ressemble un petit peu au time machine(tm) d'Apple(tm).

Toutes les variables à régler sont présente au début du script qui s'occupe de tout sauf de l'administration des exports NFS sur le serveur, et qu'il faudra donc faire à la main. Ici toutes les sauvegardes se font dans la racine contenue dans le répertoire exporté /nfs et chaque machine dispose de son propre répertoire avec un nom formaté avec des majuscules : Backup_Nommachine.

Les ceusses qui ont besoin de faire passer tout ça via internet pour effectuer leur sauvegarde "ailleurs" pourront très facilement utiliser un canal chiffré sans se casser la tête. Les sauvegardes longues qui dépassent la durée d'un cycle (par exemple chez moi, qui durent plus de 24h) sont gérées par un "lock file", et le ménage suite à un arrêt brutal ou un erreur est fait via les instructions TRAP disposées par ci par là. il y a par ailleurs "beaucoup" de commande de log... libre à chacun d'en mettre autant qu'il le souhaite.

Une prochaine version comprendra peut être la gestion automatique du remplissage de l'espace de sauvegarde. Mais ceci est déjà une autre histoire.

J'accepte toutes les critiques et les suggestions constructives. :-)


#!/bin/ksh
#
# (c) E.Huiban 2012.
#
####################

#
# Date computation
#
##################

DATE=`date "+%Y-%m-%dT%H:%M:%S"`

#
# Active directories
#
####################
DRIVE='mybookworld'
BACKUP='/nfs/Backup'
COMPUTER=$(hostname -s | perl -pe 's/^(.)/\u$1/' ) 
MOUNT="/mnt/backup"
SOURCE="/home"
DESTINATION="back-"${DATE}

#
# Exclude stack...
#
##################
EXCLUDE='--exclude='${MOUNT}
EXCLUDE=${EXCLUDE}' --exclude=tmp/' 

#
# Misc. Options...
#
##################
OPTIONS='-q -h -r -l -p -t -g -o -D -E -H -P -z --numeric-ids'
LOGGER="/usr/bin/logger -p local1.notice -t BACKUPDISK"
LOCKFILE="/var/run/backup.lock"
RSYNC="/usr/local/bin/rsync"

#
# Backup process ...
#
####################
if [ ! -e ${LOCKFILE} ]; 
  then    trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT ;
        touch ${LOCKFILE} ;
        $LOGGER 'Locked '${DATE}
        #
        # Start of critical section !!
        #
        ##############################
        #
        # Establish NFS temporary mount
        ###############################
        if ( mount -a -t nfs ${DRIVE}':'${BACKUP}'_'${COMPUTER} ${MOUNT} ) ;
                then ${LOGGER} 'Mount '${DATE} ;
                else ${LOGGER} 'Mount Error '${DATE} ; 
        fi
        #
        # Check it twice...
        #
        ###################
        if ( mount | grep -q -i ${DRIVE}':'${BACKUP}'_'${COMPUTER}' on '${MOUNT}' type nfs' ) ;
                then  echo ; 
                else ${LOGGER} 'Mount Not Present '${DATE} ;
                exit 1 ;
        fi
        #
        # Initialisation of pointer "current'.
        #
        #######################################
        if  [[ -a ${MOUNT}/back-initial ]];
                then if [[ -d ${MOUNT}/back-initial ]] ;
                        then echo ;  
                        else rm ${MOUNT}/back-initial ;
                             mkdir ${MOUNT}/back-initial ;
                             if [[ -a ${MOUNT}/current ]] ;
                                then rm ${MOUNT}/current ;
                                fi ;
                             ln -s ${MOUNT}/back-initial ${MOUNT}/current ;
                             ${LOGGER} 'Initial structure initialized '${DATE} ;
                        fi;
                else mkdir ${MOUNT}/back-initial ;
                     ln -s ${MOUNT}/back-initial ${MOUNT}/current ;
                     ${LOGGER} 'Initial structure created '${DATE} ;  
        fi ;
        #
        # Backup & update of the pointer "current".
        #
        #########################################
        ${LOGGER} 'Startup '${DATE} ;
        if ( ${RSYNC} ${OPTIONS} ${EXCLUDE} --link-dest=${MOUNT}/current ${SOURCE} ${MOUNT}/${DESTINATION} ) ;
                then rm -f ${MOUNT}/current ;
                     ln -s ${MOUNT}/${DESTINATION} ${MOUNT}/current ;
                     ${LOGGER} 'New current backup created '${DATE} ;
                else ${LOGGER} 'New current backup failed '${DATE} ;
        fi ;
        ${LOGGER} 'Stop '${DATE} ;
       #
       # Cancel temporay NFS mount...
       #
       ##############################
       if ( umount -t nfs $MOUNT ) ;
               then ${LOGGER} 'Unmount '${DATE} ;
               else ${LOGGER} 'Unmount Error '${DATE} ;
       fi
       #
       # Check it twice...
       #
       ###################
       if (mount | grep -q -i ${DRIVE}':'${BACKUP}'_'${COMPUTER}' on '${MOUNT}' type nfs'  ) ;
               then ${LOGGER} 'Mount still present '${DATE} ;
       fi
       #
       # End of critical section !
       #
       ###########################
       rm ${LOCKFILE} ;
       ${LOGGER} 'Released '${DATE} ;
       trap - INT TERM EXIT ;
else
       #
       # When time gets longer and longer...
       #
       #####################################
       ${LOGGER} 'Already running '${DATE} ;
fi  
#
# EOF
#