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 24/06/2009, à 15:19

Havany

Script bash de sauvegarde /home à améliorer...

Bonjour à tous,

Je viens d'écrire un script de sauvegarde de /home. Je me suis inspiré d'un script déjà existant, écris par mon "chef" (il aime pas que je dise chef wink), lui même inspiré de deux script écris par des personnes figurant en entête de mon script. J'y ais mis une license GPL (sûrement pas valide car incomplète) en espérant que s'il est modifié ou amélioré, je puisse être au courant de ces modifications/améliorations.

Tout fonctionne bien, mais je voudrais modifier un petit détail (peut-être pas si petit d'ailleurs).

Je m'explique :
Il y a 5 options possible dans mon script :
-s|--src pour le chemin de la source
-D|--dest-dir pour le chemin de destination
-d|--dest-dev pour la partition de destination
-l|--label pour le label de la partition de destination
-h|--help pour l'aide

Ce que je voudrais c'est que lorsque je rentre en argument des options -s|--src ou -D|--dest-dir un chemin contenant des espaces, pouvoir récupérer tout le chemin et non pas m'arrêter au premier espace rencontré.
Donc si quelqu'un avait une idée et pouvait m'aider à trouver une solution, ce serait génial.

Merci d'avance...

Voici le contenu du script :

#!/bin/bash
##############################################################################
# Save.sh  -- version 0.1 -- 2009-06-24
# Type `./Save.sh -h` for more information.
##############################################################################
#
# Personal directories snapshot utility
#
# Copyright (C) 2009 Arnaud Cruzel 
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
#
# or get it from http://www.fsf.org/licensing/licenses/gpl.html
#
#
# CREDITS/HISTORY
#
# ##########################################################################
# # make_snapshot.bash  -- version 0.1 -- 2002-12-09                       #
# # Type `./make_snapshot.bash -h` for more information.                   #
# # by Elio Pizzottelli, elio@tovel.it                                     #
# ##########################################################################

# ##########################################################################
# # mikes handy rotating-filesystem-snapshot utility                       #
# # RCS info: $Id: make_snapshot.sh,v 1.6 2002/04/06 04:20:00 mrubel Exp $ #
# # http://www.mikerubel.org/computers/rsync_snapshots/                    #
# ##########################################################################
#
############################################################################
# # FWSaveAll.bash  -- version 0.5 -- 2005-05-26                           #
# # Type `./FWSaveAll.bash -h` for more information.                       #
# # by Jean-Daniel Tissot http://chrono-environnement.univ-fcomte.fr/      #
############################################################################
#
# Adapted for a saving of the personal directories.
#

set +f            # Filename completion on
export LC_TIME="C";


#
# Unset functions already set
#    (for security)
#
unset -f usage
unset -f Wait
unset -f UmBackup
unset -f RsyncErr

#################################
#    <DefaultValues>        #
#################################

#
# System commands used here
#    (for security)
#
unset PATH

ID=/usr/bin/id;
ECHO=/bin/echo;
BASENAME=/usr/bin/basename;

WC=/usr/bin/wc;
HEAD=/usr/bin/head;
SED=/bin/sed;
AWK=/usr/bin/awk;
PRINT=/usr/bin/print;
GREP=/bin/grep;

LS=/bin/ls;
TOUCH=/usr/bin/touch;
RMDIR=/bin/rmdir;
RM=/bin/rm;
CP=/bin/cp;

DATE=/bin/date;
CAL=/usr/bin/cal;

GETOPT=/usr/bin/getopt;

MOUNT=/bin/mount;
UMOUNT=/bin/umount;
MKDIR=/bin/mkdir;
DF=/bin/df;

RSYNC=/usr/bin/rsync;

script=`${BASENAME} $0`;

#
# Set variable
#
DestDev="";
DestLabel="";
DestDir="";
Src="/home";

#
# Set backup name
#
day=`${DATE} +%d`;
month=`${DATE} +%m`;
year=`${DATE} +%y`;

backupname="backup.${year}-${month}-${day}";

#
# Set funtion
#

function Wait ()
{
if [ "${NoPause}" != "1" ]; then
    ${ECHO} -en "\nPress ENTER to continue... \b";
    read;
fi
}

function UmBackup ()
{
${UMOUNT} /Backup;
    if [ $? -ne 0 ]; then
        ${ECHO} -e "\nTrying to force umount from /Backup...";
        ${UMOUNT} -f /Backup;
    fi
${RMDIR} /Backup;
}

function RsyncErr ()
{
NS=`${GREP} "No space left on device" /var/log/${script}/error.log | ${WC} -l`;
    if [ ${NS} != 0 ]; then    
        ${ECHO} -e "\nError: ${DestDir}${DestLabel}${DestDev} is full. Operation aborded.\nDeleting ${backupname}..."
        Full=1;
    else
        ${ECHO} -e "\nError: some error during the save, see /var/log/${script}/error.log";
        Full=0;
    fi
}

function usage ()
{
    ${ECHO} "
Usage:

${script}    [-no|--no-pause --overwrite]
        [-d|--dest-dev device | -l|--label device_label] 
        [-D|--dest-dir destination_directory]
        [-s|--src source]

${script}    [-h|--help]


Explanation:

device            : a partition device.
device_label        : a partition device named by label.
destination_directory    : a valid directory (can't be on Root partition).
source            : a valid directory (defaulted to /home).


Options:

-n|--no-pause        : no breaks during the script.
-o|--overwrite        : overwrite automatically the day backup even if it exists


Example:

 ${script} -s /home/USERNAME -l MyBackup
 ${script} -s /home/USERNAME -d /dev/sdb2
 ${script} -s /home/USERNAME -D /home/USERNAME/MyBackup
";
}



#
# Check if arguments are given
#
if [ $# = 0 ] ; then
    ${ECHO} -e "\nError: no arguments.\n\tType ${script} -h for help.";
    Wait;
    exit 1;
fi


#
# Parsing arguments and options
#
TEMP=`${GETOPT} -o hnos:d:D:l: --long help,no-pause,--overwrite,--src:,dest-dev:,dest-dir:,label: -n ${script} -- "$@"`
if [ $? != 0 ] ; then
    ${ECHO} -e "\nError parsing arguments and options\n\tType ${script} -h for more information";
    Wait;    
    exit 1;
fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "${TEMP}"
while true ; do
    case $1 in
        -o|--overwrite)
            Overwrite=1
            shift;;        
        -n|--no-pause)
            NoPause=1;
            shift;;        
        -d|--dest-dev)
            if [ ! -b $2 ]; then
                ${ECHO} -e "\nError: Option -d|--dest-dev requires a valid argument";
                Wait;                
                exit 1;
            fi
            DestDev="$2";
            DestLabel="";
            shift 2;;
        -D|--dest-dir)
            if [ ! -d "$2" ]; then
                ${ECHO} -e "\nError: Option -D|--dest-dir requires a valid argument";
                Wait;                
                exit 1;
            fi
            DestDir="$2";
            DestLabel="";
            shift 2;;
        -l|--label)
            if [ -d $2 ] || [ -b $2 ]; then
                ${ECHO} -e "\nError: $2 is not a label. Option -l|--label requires a valid argument";
                Wait;                
                exit 1;            
            fi            
            case $2 in
                -*)
                    ${ECHO} -e "\nError: Option -l|--label requires a valid argument";
                    Wait;                    
                    exit 1;;
                *)
                    DestLabel="$2";
                    shift 2;;
            esac;;
        -s|--src)
            if [ ! -d "$2" ]; then
                ${ECHO} -e "\nError: Option -s|--src requires a valid argument";
                Wait;
                exit 1;
            fi
            Src="$2";
            shift 2;;
        --)
            shift;
            break;;
        -h|--help)
            usage;            
            exit 0;;
        *)
            ${ECHO} -e "\nError: unrecognized option.\n\tType ${script} -h for more information";
            Wait;            
            exit 1;;
    esac
done

#
# Make sure we're running as root
#
if (( `${ID} -u` != 0 )); then
    ${ECHO} -e "\nError: must be root. Exiting...";
    Wait;    
    exit 1;
fi

#
# Testing if required parameter have not error
#

if [ -z "${Src}" ]; then
    ${ECHO} -e "\nError: Required parameter -s|--src \n\tType ${script} -h for more information.";
    Wait;    
    exit 1;
fi

if [ -z "${DestDev}" ] && [ -z "${DestDir}" ] && [ -z "${DestLabel}" ]; then
    ${ECHO} -e "\nError: Required parameter -d|--dest-dev device OR -D|--dest-dir directory OR -l|--label label \n\tType ${script} -h for more information.";
    Wait;    
    exit 1;
fi

if ( [ ! -z "${DestDev}" ] && [ ! -z "${DestDir}" ] ) || ( [ ! -z "${DestDev}" ] && [ ! -z "${DestLabel}" ] ) || ( [ ! -z "${DestDir}" ] && [ ! -z "${DestLabel}" ] ); then
    ${ECHO} -e "\nError: Requiered only one of those parameter -d|--dest-dev device OR -D|--dest-dir directory OR -l|--label label \n\tType ${script} -h for more information.";
    Wait;
    exit 1;
fi

if [ ! -z ${DestDir} ]; then
    MountPoint=`${DF} -h ${DestDir} | ${GREP} / | ${AWK} '{ print $6 }'`;
    if [ "${MountPoint}" == "/" ]; then
        ${ECHO} -e "\nError: the destination directory can't be on Root partition \n\tType ${script} -h for more information.";
        Wait;
        exit 8;
    fi
fi

#
# Mounting device readwrite
#

if [ ! -z "${DestLabel}" ]; then
    ${MKDIR} /Backup 2>/dev/null;    
    ${MOUNT} -o rw,acl,user_xattr -L ${DestLabel} /Backup 2>/dev/null
    if [ $? -ne 0 ]; then
        ${ECHO} -e "\nTrying to remount ${DestLabel} on /Backup readwrite...";
        ${MOUNT} -o remount,rw,acl,user_xattr -L ${DestLabel} /Backup 2>/dev/null
        if [ $? -ne 0 ]; then
            ${ECHO} -e "\nError: could not remount ${DestLabel} on /Backup readwrite";
            ${RMDIR} /Backup;            
            Wait;            
            exit 32;
        fi
    fi
elif [ ! -z "${DestDev}" ]; then
    ${MKDIR} /Backup 2>/dev/null;
    ${MOUNT} -o rw,acl,user_xattr ${DestDev} /Backup 2>/dev/null
    if [ $? -ne 0 ]; then
        ${ECHO} -e "\Trying to remount ${DestDev} on /Backup readwrite...";
        ${MOUNT} -o remount,rw,acl,user_xattr ${DestDev} /Backup 2>/dev/null
        if [ $? -ne 0 ]; then
            ${ECHO} -e "\nError: could not remount ${DestDev} on /Backup readwrite";
            ${RMDIR} /Backup;            
            Wait;            
            exit 32;
        fi
    fi
elif [ ! -z "${DestDir}" ];  then
    ${ECHO} "" >/dev/null;    
else
    ${ECHO} -e "\nError: could not mount backup device (bad parameters) OR backup destination directory not set";
    Wait;    
    exit 32;
fi

#
# Some infos to sdtout
#
if [ -z "${DestDir}" ] && [ ! -z ${DestDev} ] || [ ! -z ${DestLabel} ]; then
    Size=`${DF} -h /Backup | ${GREP} /Backup | ${AWK} '{ print $4 }'`;
else
    DestWSl=`${ECHO} "${DestDir}" | ${SED} -e "s/\/$//"`;    
    Size=`${DF} -h ${DestWSl} | ${GREP} / | ${AWK} '{ print $4 }'`;
fi
${ECHO} "
Source                =${Src}
Destination device        =${DestDev}
Destination directory        ="${DestDir}"
Destination Label        =${DestLabel}
Free space on destination    =${Size}

Please don't use your computer during the backup...";

#
# The real job
#
${MKDIR} /var/log/${script} 2>/dev/null;
${TOUCH} /var/log/${script}/error.log;
if [ ! -z "${DestLabel}" ] || [ ! -z "${DestDev}" ]; then
    BackupCount=`${LS} -1dt /Backup/backup.*/ 2>/dev/null| ${WC} -l`; # Check if a backup is already exist
    if [ ${BackupCount} -ne "0" ]; then
        LastBackup=`${LS} -1dr /Backup/backup.*/ | ${HEAD} -1`;
        if [ "${LastBackup}" == "/Backup/${backupname}/" ]; then # Check if a backup of this day is already exist            
            if [ "$Overwrite" != "1" ]; then
                ${ECHO} -en "\nThe save ${backupname} already exist. Do you want to overwrite it [y/N]? : N\b";
                read ans;
                case ${ans:0:1} in
                    o|O|y|Y)
                        ${ECHO} -e "\ndeleting ${backupname}...";                    
                        ${RM} -fr /Backup/${backupname};;
                    *)
                        UmBackup;            
                        Wait;                    
                        exit 0;;
                esac
            else
                ${ECHO} -e "\ndeleting ${backupname}...";                    
                ${RM} -fr /Backup/${backupname};
            fi
        fi
        LastBackup=`${LS} -1dr /Backup/backup.*/ 2>/dev/null| ${HEAD} -1`;
        if [ ! -z "${LastBackup}" ] && [ "${LastBackup}" != "/Backup/${backupname}/" ]; then # Copy the last backup to the new backup directory
            ${ECHO} -e "\nCopy "${LastBackup}" to /Backup/${backupname}/";            
            ${CP} -al "${LastBackup}" /Backup/${backupname}/;
        fi
    fi
    ${MKDIR} /Backup/${backupname} 2>/dev/null;
    ${ECHO} -e "\nBackup is in progress. Please wait...";    
    ${RSYNC} --archive --hard-links --acls --fuzzy --delete-after --exclude=/Backup --exclude=/proc --exclude=/dev --exclude=/media --exclude=/home/*/.gvfs "${Src}" "/Backup/${backupname}"/ 2>/var/log/${script}/error.log; # Make backup on device
    if [ $? -ne 0 ]; then
        RsyncErr;        
        if [ ${Full} -eq 1 ]; then        
            ${RM} -fr /Backup/${backupname}/;
            UmBackup;            
            Wait;            
            exit 16;        
        else
            UmBackup;
            Wait;            
            exit 16;
        fi    
    fi
    UmBackup;
elif [ ! -z "${DestDir}" ]; then
    BackupCount=`${LS} -1dt "${DestDir}"backup.*/ 2>/dev/null| ${WC} -l`; # Check if a backup is already exist
    if [ ${BackupCount} -ne "0" ]; then
        LastBackup=`${LS} -1dr "${DestDir}"backup.*/ | ${HEAD} -1`;
        if [ "${LastBackup}" == "${DestDir}"${backupname}/ ]; then # Check if a backup of this day is already exist
            if [ "$Overwrite" != "1" ]; then            
                ${ECHO} -en "\nThe save ${backupname} already exist. Do you want to overwrite it [y/N]? : N\b";
                read ans;
                case ${ans:0:1} in
                    o|O|y|Y)
                        ${ECHO} -e "\ndeleting ${backupname}...";                    
                        ${RM} -fr "${DestDir}"${backupname}/;;
                    *)            
                        Wait;                    
                        exit 0;;
                esac
            else
                ${ECHO} -e "\ndeleting ${backupname}...";                    
                ${RM} -fr "${DestDir}"${backupname}/;
            fi
        fi
        LastBackup=`${LS} -1dr "${DestDir}"backup.*/ 2>/dev/null| ${HEAD} -1`;
        if [ ! -z "${LastBackup}" ] && [ "${LastBackup}" != "${DestDir}"${backupname}/ ]; then # Copy the last backup to the new backup directory
            ${ECHO} -e "\nCopy "${LastBackup}" to "${DestDir}"${backupname}";            
            ${CP} -al "${LastBackup}" "${DestDir}"${backupname};
        fi
    fi    
    ${MKDIR} "${DestDir}"${backupname} 2>/dev/null;
    ${ECHO} -e "\nBackup is in progress. Please wait...";
    ${RSYNC} --archive --hard-links --acls --fuzzy --delete-after --exclude="${DestDir}"${backupname} --exclude=/proc --exclude=/dev --exclude=/media --exclude=/home/*/.gvfs "${Src}" "${DestDir}"${backupname}/ 2>/var/log/${script}/error.log; # Make backup on directory
    if [ $? -ne 0 ]; then
        RsyncErr;
        if [ ${Full} -eq 1 ]; then    
            ${RM} -fr "${DestDir}"${backupname};            
            Wait;            
            exit 16;        
        else
            Wait;            
            exit 16;
        fi
    fi
fi

${ECHO} -e "\nEnd whithout errors";
Wait;
exit 0;

La version francisée, grand merci à michel dont je n'ai pas d'autre info, qui a effectué cette francisation :

#!/bin/bash
##############################################################################
# Save.sh  -- version 0.1 -- 2009-06-24
# Après l'invite symbolisée par "~$", Taper :
# ~$ ./Save.sh -h
# pour plus d'information.
##############################################################################
#
# Utilitaire pour copier "en l'état" le répertoire personnel
# Adapté pour faire une copie de sauvegarde des fichiers du répertoire
# personnel et de ses sous-répertoires.
#
# Copyright (C) 2009 Arnaud Cruzel arnaud.cruzel <at> laposte.net
# Traduit par Michel Decollogne marc.de.bourgogne <at> free.fr
#
# Ce programme est libre de droits. Vous pouvez le redistribuer et/ou le
# modifier selon les termes de la GNU licence publique GPLv3 "GNU General
# Public License version 3" publiée par la Free Software Foundation (FSF).
# Si la FSF fait évoluer la GPLv3, nous acceptons les modifications proposées
# par cette fondation.
# Note : GNU was launched in 1984 to develop a complete Unix-like operating
# system which is free software— software which respects your freedom.
#
# Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE
# GARANTIE ; sans GARANTIE implicite de VALEUR MARCHANDE ; sans GARANTIE
# concernant votre MATERIEL ou de FORME PHYSIQUE POUR UN BUT PARTICULIER.
# Voyez le permis de grand public de GNU pour plus de détails.
#
# Vous devriez avoir reçu une copie du permis de grand public de GNU avec ce
# programme ; sinon, écrivez à :
# Free Software Foundation, inc.,
# 51 Franklin Street
# Fifth Floor
# Boston, MA 02110-1301
# Etats-Unis
# 
# ou prenez connaissance de cette licence par Internet :
# http://www.fsf.org/licensing/licenses/gpl.html
#
#
# REMERCIEMENTS et HISTORIQUE
#
# ##########################################################################
# # Translare by:                                                          #
# # Traduit par :      Michel Decollogne - 2010-08-05                      #
# # Adresse courriel : marc.de.bourgogne <at> free.fr                      #
# ##########################################################################
#
# ##########################################################################
# # make_snapshot.bash  -- version 0.1 -- 2002-12-09                       #
# # Type `./make_snapshot.bash -h` for more information.                   #
# # by Elio Pizzottelli at: elio <at> tovel.it                             #
# ##########################################################################
#
# ##########################################################################
# # mikes handy rotating-filesystem-snapshot utility                       #
# # RCS info: $Id: make_snapshot.sh,v 1.6 2002/04/06 04:20:00 mrubel Exp $ #
# # http://www.mikerubel.org/computers/rsync_snapshots/                    #
# ##########################################################################
#
############################################################################
# # FWSaveAll.bash  -- version 0.5 -- 2005-05-26                           #
# # Type `./FWSaveAll.bash -h` for more information.                       #
# # by Jean-Daniel Tissot http://chrono-environnement.univ-fcomte.fr/      #
############################################################################
#
# Voici cette version traduite
#

set +f            # Filename completion on
                  # Complétion du nom de fichier sur
export LC_TIME="C";


# FR
# Fonctions supprimées déjà assignées
#    (pour la sécurité)
#
# EN
# Unset functions already set
#    (for security)
#
unset -f usage
unset -f Wait
unset -f UmBackup
unset -f RsyncErr

#################################
#        <DefaultValues>        #
#################################

# FR
# Commandes du système utilisées ici
#    (for security)
#
# EN
# System commands used here
#    (for security)
#
unset PATH

ID=/usr/bin/id;
ECHO=/bin/echo;
BASENAME=/usr/bin/basename;

WC=/usr/bin/wc;
HEAD=/usr/bin/head;
SED=/bin/sed;
AWK=/usr/bin/awk;
PRINT=/usr/bin/print;
GREP=/bin/grep;

LS=/bin/ls;
TOUCH=/usr/bin/touch;
RMDIR=/bin/rmdir;
RM=/bin/rm;
CP=/bin/cp;

DATE=/bin/date;
CAL=/usr/bin/cal;

GETOPT=/usr/bin/getopt;

MOUNT=/bin/mount;
UMOUNT=/bin/umount;
MKDIR=/bin/mkdir;
DF=/bin/df;

RSYNC=/usr/bin/rsync;

script=`${BASENAME} $0`;

# FR
# Assignation des variables
#
# EN
# Set variable
#
DestDev="";
DestLabel="";
DestDir="";
Src="/home";

# FR
# Assignation du nom de sauvegarde
#
# EN
# Set backup name
#
day=`${DATE} +%d`;
month=`${DATE} +%m`;
year=`${DATE} +%y`;

backupname="backup.${year}-${month}-${day}";


# FR
# Définition des fonctions
#
# EN
# Set funtion
#

function Wait ()
{
if [ "${NoPause}" != "1" ]; then
#   ${ECHO} -en "\nPress ENTER to continue... \b";
    ${ECHO} -en "\nPressez la touche Entrée pour continuer... \b";
    read;
fi
}

function UmBackup ()
{
${UMOUNT} /Backup;
    if [ $? -ne 0 ]; then
#       ${ECHO} -e "\nTrying to force umount from /Backup...";
        ${ECHO} -e "\nEssaie de forcer le démontage de /Backup...";
# NDT : Je pense que trying est un mot et non une fonction ici

        ${UMOUNT} -f /Backup;
    fi
${RMDIR} /Backup;
}

function RsyncErr ()
{
NS=`${GREP} "No space left on device" /var/log/${script}/error.log | ${WC} -l`;
    if [ ${NS} != 0 ]; then
#       ${ECHO} -e "\nError: ${DestDir}${DestLabel}${DestDev} is full. Operation aborded.\nDeleting ${backupname}..."
        ${ECHO} -e "\nErreur : ${DestDir}${DestLabel}${DestDev} est plein. Opération abandonnée. \nEffacer ${backupname}..."
        Full=1;
# NDT : J'espère que l'on peut traduire le mot "Error"
# NDT : J'espère que l'on peut traduire le mot "Deleting"

    else
#       ${ECHO} -e "\nError: some error during the save, see /var/log/${script}/error.log";
        ${ECHO} -e "\nErreur : il y a eu quelque(s) erreur(s) durant la sauvegarde, voir /var/log/${script}/error.log";
# NDT : J'espère que l'on peut traduire le mot "Error"
        Full=0;
    fi
}

function usage ()
{
    ${ECHO} "
# Usage:
Utilisation :

${script}    [-no|--no-pause --overwrite]
#       [-d|--dest-dev device | -l|--label device_label] 
        [-d|--dest-dev partition_de_disque | -l|--label nom_de_la_partition] 
#       [-D|--dest-dir destination_directory]
        [-D|--dest-dir répertoire_de_destination]
        [-s|--src source]

${script}    [-h|--help]

# Explanation:
Explications :

# device            : a partition device.
device            : un disque ou une partition d'un disque ou une clé USB.
# device_label        : a partition device named by label.
device_label        : partition désignée par son nom ou étiquette (ou label).
# destination_directory    : a valid directory (can't be on Root partition).
destination_directory    : un répertoire valide
                           qui ne doit pas être sur la partition root.
# source            : a valid directory (defaulted to /home).
source            : un répertoire valide (par défaut c'est /home).
                    Vous pouvez préférer /home/votre_nom_d_utilisateur
                    si vous êtes plusieurs utilisateurs.

# Options:
Options :

# -n|--no-pause        : no breaks during the script.
-n|--no-pause        : ne fait pas d'arrêt durant l'exécution du script.
# -o|--overwrite        : overwrite automatically the day backup even if it exists
-o|--overwrite        : ré-écrit automatiquement la date du jour
                        même si le fichier existe

# Example:
Exemple :

 ${script} -s /home/USERNAME -l MyBackup
 ${script} -s /home/USERNAME -d /dev/sdb2
 ${script} -s /home/USERNAME -D /home/USERNAME/MyBackup
";
}



# FR
# Vérifier si les arguments sont donnés
#
# EN
# Check if arguments are given
#
if [ $# = 0 ] ; then
#   ${ECHO} -e "\nError: no arguments.\n\tType ${script} -h for help.";
    ${ECHO} -e "\nErreur : pas d'argument. \n\tTapez ${script} -h pour de l'aide.";
# NDT : J'espère que l'on peut traduire le mot "Error"
# NDT : Dans l'expression "\n\tType ${script} -h" peut-on traduire "Type" par "Tapez" ?
    Wait;
    exit 1;
fi


# FR
# Analyse des arguments et options
#
# EN
# Parsing arguments and options
#
TEMP=`${GETOPT} -o hnos:d:D:l: --long help,no-pause,--overwrite,--src:,dest-dev:,dest-dir:,label: -n ${script} -- "$@"`
if [ $? != 0 ] ; then
#   ${ECHO} -e "\nError parsing arguments and options\n\tType ${script} -h for more information";
    ${ECHO} -e "\nErreur d'analyse des arguments et options. \n\tTapez ${script} -h pour de l'aide.";
# NDT : J'espère que l'on peut traduire le mot "Error"
# NDT : J'espère que l'on peut traduire le mot "Type"
    Wait;
    exit 1;
fi

# Note the quotes around `$TEMP': they are essential!
# Notez les guillemets autour de "$TEMP", ils sont importants !
# NDT : pourquoi mettre des guillemets simples dans le commentaire et
# des guillemets doubles dans le script ?
eval set -- "${TEMP}"
while true ; do
    case $1 in
        -o|--overwrite)
            Overwrite=1
            shift;;
        -n|--no-pause)
            NoPause=1;
            shift;;
        -d|--dest-dev)
            if [ ! -b $2 ]; then
#               ${ECHO} -e "\nError: Option -d|--dest-dev requires a valid argument";
                ${ECHO} -e "\nErreur : Option -d|--dest-dev requise pour argument valide.":
# NDT : J'espère que l'on peut traduire le mot "Error"
                Wait;
                exit 1;
            fi
            DestDev="$2";
            DestLabel="";
            shift 2;;
        -D|--dest-dir)
            if [ ! -d "$2" ]; then
#               ${ECHO} -e "\nError: Option -D|--dest-dir requires a valid argument";
                ${ECHO} -e "\nErreur : Option -D|--dest-dir requise pour argument valide.":
# NDT : J'espère que l'on peut traduire le mot "Error"
                Wait;
                exit 1;
            fi
            DestDir="$2";
            DestLabel="";
            shift 2;;
        -l|--label)
            if [ -d $2 ] || [ -b $2 ]; then
#               ${ECHO} -e "\nError: $2 is not a label. Option -l|--label requires a valid argument";
                ${ECHO} -e "\nErreur : $2 n'est pas une destination connue. 
                              Option -l|--label requise pour argument valide.":
# NDT : J'espère que l'on peut traduire le mot "Error"
                Wait;
                exit 1;
            fi
            case $2 in
                -*)
#                   ${ECHO} -e "\nError: Option -l|--label requires a valid argument";
                    ${ECHO} -e "\nErreur : Option -l|--label requise pour argument valide.":
# NDT : J'espère que l'on peut traduire le mot "Error"
                    Wait;
                    exit 1;;
                *)
                    DestLabel="$2";
                    shift 2;;
            esac;;
        -s|--src)
            if [ ! -d "$2" ]; then
#               ${ECHO} -e "\nError: Option -s|--src requires a valid argument";
                ${ECHO} -e "\nErreur : Option -s|--src requise pour argument valide.":
# NDT : J'espère que l'on peut traduire le mot "Error"
                Wait;
                exit 1;
            fi
            Src="$2";
            shift 2;;
        --)
            shift;
            break;;
        -h|--help)
            usage;
            exit 0;;
        *)
#           ${ECHO} -e "\nError: unrecognized option.\n\tType ${script} -h for more information";
            ${ECHO} -e "\nErreur : option non reconnue. \n\tTapez ${script} -h pour de l'aide.";
# NDT : J'espère que l'on peut traduire le mot "Error"
# NDT : J'espère que l'on peut traduire le mot "Type"
            Wait;
            exit 1;;
    esac
done

# FR
# Cette séquence s'assure que vous fonctionnez en root
#
# EN
# Make sure we're running as root
#
if (( `${ID} -u` != 0 )); then
#   ${ECHO} -e "\nError: must be root. Exiting...";
    ${ECHO} -e "\nErreur : seul l'utilisateur root peut agir.";
# NDT : J'espère que l'on peut traduire le mot "Error"
    Wait;
    exit 1;
fi

# FR
# Teste si les paramètres requis n'ont pas d'erreur
#
# EN
# Testing if required parameter have not error
#

if [ -z "${Src}" ]; then
#   ${ECHO} -e "\nError: Required parameter -s|--src \n\tType ${script} -h for more information.";
    ${ECHO} -e "\nErreur : paramètre requis -s|--src 
         OU \n\tTapez ${script} -h pour de l'aide.";
# NDT : J'espère que l'on peut traduire le mot "Error"
# NDT : J'espère que l'on peut traduire le mot "Type"
    Wait;
    exit 1;
fi

if [ -z "${DestDev}" ] && [ -z "${DestDir}" ] && [ -z "${DestLabel}" ]; then
#   ${ECHO} -e "\nError: Required parameter -d|--dest-dev device OR -D|--dest-dir directory OR -l|--label label \n\tType ${script} -h for more information.";
    ${ECHO} -e "\nErreur : paramètre requis -d|--dest-dev device 
         OU -D|--dest-dir directory
         OU -l|--label label
         OU \n\tTapez ${script} -h pour de l'aide.";
# NDT : J'espère que l'on peut traduire le mot "Error"
# NDT : J'espère que l'on peut traduire le mot "Type"
    Wait;
    exit 1;
fi

if ( [ ! -z "${DestDev}" ] && [ ! -z "${DestDir}" ] ) || ( [ ! -z "${DestDev}" ] && [ ! -z "${DestLabel}" ] ) || ( [ ! -z "${DestDir}" ] && [ ! -z "${DestLabel}" ] ); then
#   ${ECHO} -e "\nError: Requiered only one of those parameter -d|--dest-dev device OR -D|--dest-dir directory OR -l|--label label \n\tType ${script} -h for more information.";
    ${ECHO} -e "\nErreur : un seul de ces paramètres est requis -d|--dest-dev device
         OU -D|--dest-dir directory
         OU -l|--label label
         OU \n\tTapez ${script} -h pour de l'aide.";
# NDT : J'espère que l'on peut traduire le mot "Error"
# NDT : J'espère que l'on peut traduire le mot "Type"
    Wait;
    exit 1;
fi

if [ ! -z ${DestDir} ]; then
    MountPoint=`${DF} -h ${DestDir} | ${GREP} / | ${AWK} '{ print $6 }'`;
    if [ "${MountPoint}" == "/" ]; then
#       ${ECHO} -e "\nError: the destination directory can't be on Root partition \n\tType ${script} -h for more information.";
        ${ECHO} -e "\nErreur : le répertoire de destination ne peut être sur la partition racine \n\tTapez ${script} -h pour de l'aide.";
# NDT : J'espère que l'on peut traduire le mot "Error"
# NDT : J'espère que l'on peut traduire le mot "Type"
        Wait;
        exit 8;
    fi
fi

# FR
# Installe le disque ou répertoire de sauvegarde en lecture/écriture
#
# EN
# Mounting device readwrite
#

if [ ! -z "${DestLabel}" ]; then
    ${MKDIR} /Backup 2>/dev/null;
    ${MOUNT} -o rw,acl,user_xattr -L ${DestLabel} /Backup 2>/dev/null
    if [ $? -ne 0 ]; then
#       ${ECHO} -e "\nTrying to remount ${DestLabel} on /Backup readwrite...";
        ${ECHO} -e "\nEssaye d'installer ${DestLabel} sur /Backup en lecture/écriture";
# NDT : Je pense que trying est un mot et non une fonction ici
        ${MOUNT} -o remount,rw,acl,user_xattr -L ${DestLabel} /Backup 2>/dev/null
        if [ $? -ne 0 ]; then
#           ${ECHO} -e "\nError: could not remount ${DestLabel} on /Backup readwrite";
            ${ECHO} -e "\nErreur : n'a pas pu installer ${DestLabel} sur /Backup en lecture/écriture";
# NDT : J'espère que l'on peut traduire le mot "Error"
            ${RMDIR} /Backup;
            Wait;
            exit 32;
        fi
    fi
elif [ ! -z "${DestDev}" ]; then
    ${MKDIR} /Backup 2>/dev/null;
    ${MOUNT} -o rw,acl,user_xattr ${DestDev} /Backup 2>/dev/null
    if [ $? -ne 0 ]; then
#       ${ECHO} -e "\Trying to remount ${DestDev} on /Backup readwrite...";
        ${ECHO} -e "\Essaye d'installer ${DestDev} sur /Backup en lecture/écriture";
# NDT : Je pense que trying est un mot et non une fonction ici
        ${MOUNT} -o remount,rw,acl,user_xattr ${DestDev} /Backup 2>/dev/null
        if [ $? -ne 0 ]; then
#           ${ECHO} -e "\nError: could not remount ${DestDev} on /Backup readwrite";
            ${ECHO} -e "\nErreur : n'a pas pu installer ${DestDev} sur /Backup en lecture/écriture";
# NDT : J'espère que l'on peut traduire le mot "Error"
            ${RMDIR} /Backup;
            Wait;
            exit 32;
        fi
    fi
elif [ ! -z "${DestDir}" ];  then
    ${ECHO} "" >/dev/null;
else
#   ${ECHO} -e "\nError: could not mount backup device (bad parameters) OR backup destination directory not set";
    ${ECHO} -e "\nErreur : ne peut pas monter le dispositif de sauvegarde (mauvais paramètres) OU le répertoire de destination de la sauvegarde n'est pas assigné ou mal défini";
# NDT : J'espère que l'on peut traduire le mot "Error"
    Wait;
    exit 32;
fi

# FR
# Envoie quelques informations au sdtout
#
# EN
# Some infos to sdtout
#
if [ -z "${DestDir}" ] && [ ! -z ${DestDev} ] || [ ! -z ${DestLabel} ]; then
    Size=`${DF} -h /Backup | ${GREP} /Backup | ${AWK} '{ print $4 }'`;
else
    DestWSl=`${ECHO} "${DestDir}" | ${SED} -e "s/\/$//"`;    
    Size=`${DF} -h ${DestWSl} | ${GREP} / | ${AWK} '{ print $4 }'`;
fi
${ECHO} "
Source                =${Src}
Destination device        =${DestDev}
Destination directory        ="${DestDir}"
Destination Label        =${DestLabel}
Free space on destination    =${Size}

N'utilisez pas votre ordinateur pendant la sauvegarde.";
# Please don't use your computer during the backup...";

# FR
# Le travail réel
#
# EN
# The real job
#
${MKDIR} /var/log/${script} 2>/dev/null;
${TOUCH} /var/log/${script}/error.log;
if [ ! -z "${DestLabel}" ] || [ ! -z "${DestDev}" ]; then
    BackupCount=`${LS} -1dt /Backup/backup.*/ 2>/dev/null| ${WC} -l`; # Check if a backup is already exist
                                                                      # Vérifie si une sauvegarde existe déjà
    if [ ${BackupCount} -ne "0" ]; then
        LastBackup=`${LS} -1dr /Backup/backup.*/ | ${HEAD} -1`;
        if [ "${LastBackup}" == "/Backup/${backupname}/" ]; then # Check if a backup of this day is already exist
                                                                 # Vérifie si une sauvegarde du même jour existe déjà
            if [ "$Overwrite" != "1" ]; then
#               ${ECHO} -en "\nThe save ${backupname} already exist. Do you want to overwrite it [y/N]? : N\b";
                ${ECHO} -en "\nLa sauvegarde ${backupname} existe déjà. Voulez-vous l'écraser [y/N]? : N\b";
                read ans;
                case ${ans:0:1} in
                    o|O|y|Y)
#                       ${ECHO} -e "\ndeleting ${backupname}...";
                        ${ECHO} -e "\neffacement de ${backupname}...";
                        ${RM} -fr /Backup/${backupname};;
                    *)
                        UmBackup;
                        Wait;
                        exit 0;;
                esac
            else
#               ${ECHO} -e "\ndeleting ${backupname}...";
                ${ECHO} -e "\neffacement de ${backupname}...";
                ${RM} -fr /Backup/${backupname};
            fi
        fi
        LastBackup=`${LS} -1dr /Backup/backup.*/ 2>/dev/null| ${HEAD} -1`;
        if [ ! -z "${LastBackup}" ] && [ "${LastBackup}" != "/Backup/${backupname}/" ]; then # Copy the last backup to the new backup directory
                                                                                             # Copie la dernière sauvegarde vers le nouveau répertoire de sauvegarde
#           ${ECHO} -e "\nCopy "${LastBackup}" to /Backup/${backupname}/";
            ${ECHO} -e "\nCopie "${LastBackup}" vers /Backup/${backupname}/";
            ${CP} -al "${LastBackup}" /Backup/${backupname}/;
        fi
    fi
    ${MKDIR} /Backup/${backupname} 2>/dev/null;
#   ${ECHO} -e "\nBackup is in progress. Please wait...";
    ${ECHO} -e "\nSauvegarde en cours. Patientez...";    
    ${RSYNC} --archive --hard-links --acls --fuzzy --delete-after --exclude=/Backup --exclude=/proc --exclude=/dev --exclude=/media --exclude=/home/*/.gvfs "${Src}" "/Backup/${backupname}"/ 2>/var/log/${script}/error.log; # Make backup on device
    if [ $? -ne 0 ]; then
        RsyncErr;
        if [ ${Full} -eq 1 ]; then
            ${RM} -fr /Backup/${backupname}/;
            UmBackup;
            Wait;
            exit 16;
        else
            UmBackup;
            Wait;
            exit 16;
        fi
    fi
    UmBackup;
elif [ ! -z "${DestDir}" ]; then
    BackupCount=`${LS} -1dt "${DestDir}"backup.*/ 2>/dev/null| ${WC} -l`; # Check if a backup is already exist
                                                                          # Vérifie si une sauvegarde existe déjà
    if [ ${BackupCount} -ne "0" ]; then
        LastBackup=`${LS} -1dr "${DestDir}"backup.*/ | ${HEAD} -1`;
        if [ "${LastBackup}" == "${DestDir}"${backupname}/ ]; then # Check if a backup of this day is already exist
                                                                   # Vérifie si une sauvegarde du même jour existe déjà
            if [ "$Overwrite" != "1" ]; then
#               ${ECHO} -en "\nThe save ${backupname} already exist. Do you want to overwrite it [y/N]? : N\b";
                ${ECHO} -en "\nLa sauvegarde ${backupname} existe déjà. Voulez-vous l'écraser [y/N]? : N\b";
                read ans;
                case ${ans:0:1} in
                    o|O|y|Y)
#                       ${ECHO} -e "\ndeleting ${backupname}...";
                        ${ECHO} -e "\nEffacement de ${backupname}...";
                        ${RM} -fr "${DestDir}"${backupname}/;;
                    *)
                        Wait;
                        exit 0;;
                esac
            else
#               ${ECHO} -e "\ndeleting ${backupname}...";
                ${ECHO} -e "\nEffacement de ${backupname}...";
                ${RM} -fr "${DestDir}"${backupname}/;
            fi
        fi
        LastBackup=`${LS} -1dr "${DestDir}"backup.*/ 2>/dev/null| ${HEAD} -1`;
        if [ ! -z "${LastBackup}" ] && [ "${LastBackup}" != "${DestDir}"${backupname}/ ]; then # Copy the last backup to the new backup directory
                                                                                               # Copie la dernière sauvegarde vers le nouveau répertoire de sauvegarde
#           ${ECHO} -e "\nCopy "${LastBackup}" to "${DestDir}"${backupname}";
            ${ECHO} -e "\nCopie "${LastBackup}" vers "${DestDir}"${backupname}";
            ${CP} -al "${LastBackup}" "${DestDir}"${backupname};
        fi
    fi
    ${MKDIR} "${DestDir}"${backupname} 2>/dev/null;
#   ${ECHO} -e "\nBackup is in progress. Please wait...";
    ${ECHO} -e "\nSauvegarde en cours. Patientez...";
    ${RSYNC} --archive --hard-links --acls --fuzzy --delete-after --exclude="${DestDir}"${backupname} --exclude=/proc --exclude=/dev --exclude=/media --exclude=/home/*/.gvfs "${Src}" "${DestDir}"${backupname}/ 2>/var/log/${script}/error.log; # Make backup on directory
    if [ $? -ne 0 ]; then
        RsyncErr;
        if [ ${Full} -eq 1 ]; then
            ${RM} -fr "${DestDir}"${backupname};
            Wait;
            exit 16;
        else
            Wait;
            exit 16;
        fi
    fi
fi

# ${ECHO} -e "\nEnd whithout errors";
${ECHO} -e "\nSauvegarde terminée sans erreurs.";
# NDT Si la personne n'est pas devant son PC il faudrait taper une touche pour qu'il voit ce message
# est-ce que l'instruction ci-dessous "wait" attend une action sur le clavier ?
Wait;
exit 0;

édit : Bien évidement je suis ouvert à toutes autres suggestions...


édit du 25/06/2009 : Modification du script : 2 options suplémentaires (-o|--overwrite et -n|--no-pause) "nom_du_script -h" pour plus d'info. Et correction de quelques bugs.

édit du 01/07/2009 : Correction d'un bug dans la recherche de la dernière sauvegarde.

édit du 09/07/2009 : Correction d'un bug dans la vérification de la cohérence des arguments.

Dernière modification par Havany (Le 10/12/2011, à 17:32)

Hors ligne

#2 Le 24/06/2009, à 15:53

Havany

Re : Script bash de sauvegarde /home à améliorer...

Pour ceux qui veulent juste utiliser ce script, la procédure :

1-Copier le contenu du script dans un fichier texte.

2-Enregistrer le fichier en l'appelant save.sh (on peut tout à fait le nommer autrement).

3-Lui donner les droits d'exécution :

sudo chmod +x /chemin/du/script/nom_du_script

4-Il peut être interessant aussi de rendre root propriétaire :

sudo chown root:root /chemin/du/script/nom_du_script

5-Pour savoir comment l'utiliser :

/chemin/du/script/nom_du_script -h

Hors ligne

#3 Le 25/06/2009, à 00:29

BorX

Re : Script bash de sauvegarde /home à améliorer...

L'espace sépare les arguments. Donc, comme avec n'importe quelle commande Shell (ls, cat, vi, cp, mv, rm, ...) si tu laisses les espaces, tu as plusieurs arguments et puis c'est tout. smile

Il faut "dire" au Shell que ce qu'il considère comme étant 2 arguments n'en est en fait qu'un seul.
Et pour n'en faire qu'un seul argument, tu dois soit les encadrer de quotes ou de guillemets, soit échapper les espaces avant des backslashes.

$ mkdir "nom de rep avec des espaces"

$ rmdir nom de rep avec des espaces
rmdir: échec de suppression de `nom': Aucun fichier ou dossier de ce type
rmdir: échec de suppression de `de': Aucun fichier ou dossier de ce type
rmdir: échec de suppression de `rep': Aucun fichier ou dossier de ce type
rmdir: échec de suppression de `avec': Aucun fichier ou dossier de ce type
rmdir: échec de suppression de `des': Aucun fichier ou dossier de ce type
rmdir: échec de suppression de `espaces': Aucun fichier ou dossier de ce type

$ rmdir nom\ de\ rep\ avec\ des\ espaces

$


$ cat > essai.sh
#!/bin/bash
echo $1
echo $2

$ chmod +x essai.sh 

$ ./essai.sh aaa a bbb
aaa
a

$ ./essai.sh aaa\ a bbb
aaa a
bbb

$ ./essai.sh "aaa a" bbb
aaa a
bbb

$ ./essai.sh 'aaa a' bbb
aaa a
bbb

Dernière modification par BorX (Le 25/06/2009, à 00:38)

Hors ligne

#4 Le 25/06/2009, à 11:03

Havany

Re : Script bash de sauvegarde /home à améliorer...

Ça y est... J'ai trouvé.

Juste des problèmes de double quotes manquantes dans mon script.

J'ai updaté le script.

Il est maintenant opérationnel, même avec des chemins contenant des espaces.

Merci...

Dernière modification par Havany (Le 25/06/2009, à 11:03)

Hors ligne

#5 Le 25/06/2009, à 11:20

BorX

Re : Script bash de sauvegarde /home à améliorer...

Ok, je comprends mieux ton problème...

Oui, à l'invocation de ton script, tu lui files des paramètres contenant des espaces (soit avec des quotes ou des guillemets, soit en les échappant).
Mais effectivement, ensuite, les espaces qui sont passés à l'invocation de ton script peuvent poser problème au sein même de ton script.

Le Shell fonctionne par substitution : il remplace $var par sa valeur. Si cette valeur contient un espace, ça va faire 2 mots et ça peut donc poser des problèmes de syntaxe.
C'est la raison pour laquelle, à mon sens, il est bon d'encadrer toutes ses variables par des guillemets.

Typiquement, à partir de 2 lignes prises au hasard dans ton script :
Au lieu de ça :

script=`${BASENAME} $0`;
${MKDIR} /var/log/${script} 2>/dev/null;

Plutôt ça :

script="$($BASENAME $0)"
$MKDIR "/var/log/$script" 2>/dev/null

Dernière modification par BorX (Le 25/06/2009, à 11:25)

Hors ligne

#6 Le 25/06/2009, à 14:00

Havany

Re : Script bash de sauvegarde /home à améliorer...

Plutôt :

script="`${BASENAME} $0`"

Parce que ${BASENAME} est une variable pointant sur une commande.
Non ?...

Dernière modification par Havany (Le 25/06/2009, à 14:01)

Hors ligne

#7 Le 25/06/2009, à 14:34

BorX

Re : Script bash de sauvegarde /home à améliorer...

Tu as mal lu wink
Arrête avec les backquotes, c'est mal. tongue

Privilégie la syntaxe $(commande) qui te permettra, notamment, d'imbriquer des commandes. Par exemple :

var="$(ls -l $(which bash))"

Dernière modification par BorX (Le 25/06/2009, à 14:36)

Hors ligne

#8 Le 25/06/2009, à 14:35

BorX

Re : Script bash de sauvegarde /home à améliorer...

Et perso, je suis pas fan de ${var} sauf cas exceptionnel.
Je préfère $var, simplement. Mais c'est un terrain glissant entre codeurs bash et codeurs ksh.

Hors ligne

#9 Le 25/09/2010, à 16:07

Havany

Re : Script bash de sauvegarde /home à améliorer...

Bonjour,

Bon voici une nouvelle version :
*La compression lors du transfert a été supprimé, elle est inutile et lourde.
*Il y a plus d'infos concernant la durée du backup, l'espace pris etc...
*quelques beugs ont été corrigés.
*Il y a des variables par défaut : sans argument vous sauvegardez /home vers un disque usb ou interne dont le label est Rsync. À vous de le modifier à votre convenance.
*par contre je l'ai laissé en anglais


#!/bin/bash
##############################################################################
# Save.sh  -- version 0.1-2 -- 2009-06-24
# Type `./Save.sh -h` for more information.
##############################################################################
#
# Personal directories snapshot utility
#
# Copyright (C) 2009 Arnaud Cruzel arnaud.cruzel@laposte.net
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
#
# or get it from http://www.fsf.org/licensing/licenses/gpl.html
#
#
# CREDITS/HISTORY
#
# ##########################################################################
# # make_snapshot.bash  -- version 0.1 -- 2002-12-09                       #
# # Type `./make_snapshot.bash -h` for more information.                   #
# # by Elio Pizzottelli, elio@tovel.it                                     #
# ##########################################################################

# ##########################################################################
# # mikes handy rotating-filesystem-snapshot utility                       #
# # RCS info: $Id: make_snapshot.sh,v 1.6 2002/04/06 04:20:00 mrubel Exp $ #
# # http://www.mikerubel.org/computers/rsync_snapshots/                    #
# ##########################################################################
#
############################################################################
# # FWSaveAll.bash  -- version 0.5 -- 2005-05-26			   #
# # Type `./FWSaveAll.bash -h` for more information.			   #
# # by Jean-Daniel Tissot http://chrono-environnement.univ-fcomte.fr/      #
############################################################################
#
# Adapted for a saving of the personal directories.
#

set +f			# Filename completion on
export LC_TIME="C";


#
# Unset functions already set
#	(for security)
#
unset -f usage
unset -f Wait
unset -f UmBackup
unset -f RsyncErr

#################################
#	<DefaultValues>		#
#################################

#
# System commands used here
#	(for security)
#
unset PATH

ID=/usr/bin/id;
ECHO=/bin/echo;
BASENAME=/usr/bin/basename;

WC=/usr/bin/wc;
HEAD=/usr/bin/head;
SED=/bin/sed;
AWK=/usr/bin/awk;
PRINT=/usr/bin/print;
GREP=/bin/grep;
TAIL=/usr/bin/tail;

LS=/bin/ls;
TOUCH=/usr/bin/touch;
RMDIR=/bin/rmdir;
RM=/bin/rm;
CP=/bin/cp;
LN=/bin/ln;

DATE=/bin/date;
CAL=/usr/bin/cal;

GETOPT=/usr/bin/getopt;

MOUNT=/bin/mount;
UMOUNT=/bin/umount;
MKDIR=/bin/mkdir;
DF=/bin/df;
CLEAR=/usr/bin/clear;
DU=/usr/bin/du;
TR=/usr/bin/tr;
EXPR=/usr/bin/expr;
SLEEP=/bin/sleep;
CAT=/bin/cat;
PS=/bin/ps;
BC=/usr/bin/bc;
BLKID=/sbin/blkid;

RSYNC=/usr/bin/rsync;

script=`${BASENAME} $0`;

#
# Set variable
#
DestDev="";
DestLabel="Rsync";
DestDir="";
Src="/home";

#
# Set backup name
#
day=`${DATE} +%d`;
month=`${DATE} +%m`;
year=`${DATE} +%y`;

backupname="backup.${year}-${month}-${day}";
${ECHO} '' > /var/log/${script}/inf;



#
# Set funtion
#

function Wait ()
{
${ECHO} -en "Press ENTER to continue... \b";
read ans;
}

function UmBackup ()
{
${UMOUNT} /Backup;
	if [ $? -ne 0 ]; then
		${ECHO} "Trying to force umount from /Backup...";
		${UMOUNT} -f /Backup;
	fi
${RMDIR} /Backup 2>/dev/null;
}

function RsyncErr ()
{
NS=`${GREP} "No space left on device" /var/log/${script}/error.log | ${WC} -l`;
	if [ ${NS} != 0 ]; then	
		${ECHO} "Error: ${DestDir}${DestLabel}${DestDev} is full. Operation aborded, ${backupname} deleted."
		Full=1;
	else
		${ECHO} "Error: some error during the save, see /var/log/${script}/error.log";
		Full=0;
	fi
}

function deuxdigits ()
{
dg=$1
if [ `${ECHO} $dg | ${WC} -c` -eq 2 ]; then
	dg="0$dg"
fi
${ECHO} $dg
}

function percent ()
{
db=$1;
savebefrs=$2;
dsocbefrs=$3;
dsocbefrsori=$3
restori=`${ECHO} "$4 - $2" | ${BC}`;
o=$4;
datedeb=$5;
t='0';
time=0;
ERR=0;
NR=0;
tminexec=0;
tsecexec=1;
tpbclAv=1
FAv=0
#echo "savebefrs= $savebefrs o= $o restori= $restori" >>/var/log/${script}/inf

${CLEAR};
${CAT} /var/log/${script}/inf;
while [ "X$NR" != "X" ]; 
do 
	actudsoc=`${DF} -m | ${GREP} ${db} | ${AWK} '{print $3}'`;
	diffdsoc=`${ECHO} "$actudsoc - $dsocbefrs" | ${BC}`;
	t=`${ECHO} "$diffdsoc + $savebefrs" | ${BC}`;
	#o=`${DU} -ms --exclude=/home/*/.gvfs ${Src} 2>/dev/null| ${AWK} '{printf $1}' | ${TR} -d G`;
	if [ "X$t" == "X" ]; then
		${ECHO} "Error, Please Wait...";		
		exit 13;
	fi
	p=$(${EXPR} $t \* 100 / $o);
	recom=`$ECHO $tminexec % 10`
	if [[ $p -gt 100 || $t -gt $o || $recom -eq 0 && $tsecexec -eq 0 ]]; then
		o=`${DU} -ms --exclude=/home/*/.gvfs --exclude=/Backup --exclude=/proc --exclude=/dev --exclude=/media ${Src} 2>/dev/null| ${AWK} '{printf $1}' | ${TR} -d G` 
		savebefrs=`${DU} -msL ${db}/${backupname}/ 2>/dev/null| ${AWK} '{printf $1}'` 
		dsocbefrs=`${DF} -m | ${GREP} ${db} | ${AWK} '{print $3}'`;
		actudsoc=`${DF} -m | ${GREP} ${db} | ${AWK} '{print $3}'`;
		diffdsoc=`${ECHO} "$actudsoc - $dsocbefrs" | ${BC}`;
		t=`${ECHO} "$diffdsoc + $savebefrs" | ${BC}`;
		if [ "X$t" == "X" ]; then
			${ECHO} "Error, Please Wait...";		
			exit 13;
		fi
		p=$(${EXPR} $t \* 100 / $o);
	fi
		
#	${CLEAR};
#	${CAT} /var/log/${script}/inf;
#	${ECHO} -ne "$p% d'avancement\t$t/$o octets sauvegardés \n\r$pt>\r";
	to=`${EXPR} $time / 10`
	poi=0;
	pt=$(while [ $poi != `${EXPR} $p / 2` ]
	do
		${ECHO} -ne "=";
		poi=$(${EXPR} $poi + 1);
	done)
	datenow=`${DATE} +%s`;
	timeexec=`${ECHO} "$datenow - $datedeb" | ${BC}`
	tsecexec=`${ECHO} $timeexec % 60 | ${BC}`
	inttime=`${ECHO} $timeexec / 60 | ${BC}`
	tminexec=`${ECHO} $inttime % 60 | ${BC}`
	theuexec=`${ECHO} $inttime / 60 | ${BC}`
	secexec=`deuxdigits $tsecexec`
	minexec=`deuxdigits $tminexec`
	heuexec=`deuxdigits $theuexec`
	diffdsocori=`${ECHO} "$actudsoc - $dsocbefrsori" | ${BC}`
	diffbcl=`${ECHO} "$diffdsocori - $FAv" | ${BC}`
	tforbcl=`${DATE} +%s`
	tpbcl=`${ECHO} "$tforbcl - $tpbclAv" | ${BC}`
	AvSpeed1=`${ECHO} "scale=2 ; $diffdsocori / $timeexec" | ${BC} -l`
	ReSpeed=`${ECHO} "scale=2 ; $diffbcl / $tpbcl" | ${BC} -l`
	FAv=`${ECHO} $diffdsocori`
	tpbclAv=`${ECHO} $tforbcl`
	AvSpeed=`${ECHO} $AvSpeed1 | ${SED} 's/^\./0\./'`
	if [ $diffdsocori -eq 0 ]; then
		tptotal=1
	else
		#tptotal=`${ECHO} "$o * $timeexec / $diffdsocori" | ${BC}`
		tptotal=`${ECHO} "$o * $timeexec / $restori" | ${BC}`
	fi
#echo "avspeed1= $AvSpeed1 AvSpeed= $AvSpeed "  >>/var/log/${script}/inf
	#tsectotal=`${ECHO} $tptotal % 60 | ${BC}`
	tsectotal=`${ECHO} "$restori / $AvSpeed1 % 60" | ${BC}`
	intttotal=`${ECHO} "$restori / $AvSpeed1" | ${BC}`
	#intttotal=`${ECHO} $tptotal / 60 | ${BC}`
	#tmintotal=`${ECHO} $intttotal % 60 | ${BC}`
	tmintotal=`${ECHO} "$intttotal / 60 % 60" | ${BC}`
	tmintotal1=`${ECHO} $intttotal / 60 | ${BC}`
	#theutotal=`${ECHO} $intttotal / 60 | ${BC}`
	theutotal=`${ECHO} $tmintotal1 / 60 | ${BC}`
	sectotal=`deuxdigits $tsectotal`
	mintotal=`deuxdigits $tmintotal`
	heutotal=`deuxdigits $theutotal`
	${CLEAR};
	#${ECHO} $diffdsoc
	#${ECHO} "les valeurs originales : tsecexec : $tsectotal ; tminexec : $tmintotal ; theuexec : $theutotal ; timeexec : $tptotal ; o : $o ; timeexec : $timeexec ; diffdsoc : $diffdsoc"
	#${ECHO} "les valeurs finales    :  secexec : $sectotal  ; minexec : $mintotal   ; heuexec : $heutotal"
	${CAT} /var/log/${script}/inf;
	tgo=`${ECHO} $t % 1024 \* 100 / 1024 | ${BC}`
	if [ `${ECHO} $tgo | ${WC} -c` -eq 2 ]; then
		tgo="0$tgo"
	fi
	ogo=`${ECHO} $o % 1024 \* 100 / 1024 | ${BC}`
	if [ `${ECHO} $ogo | ${WC} -c` -eq 2 ]; then
                ogo="0$ogo"
        fi
	if [ $t -gt 1024 ]; then
		${ECHO} -ne "$p% d'avancement\t`${ECHO} $t / 1024 | ${BC}`,$tgo/`${ECHO} $o / 1024 | ${BC}`,$ogo Go sauvegardés\n\r$heuexec:$minexec:$secexec/$heutotal:$mintotal:$sectotal\tAvSpeed : $AvSpeed Mo/s ; Speed : $ReSpeed Mo/s\n\r$pt> $p%\r";
	else
		${ECHO} -ne "$p% d'avancement\t$t Mo/`${ECHO} $o / 1024 | ${BC}`,$ogo Go sauvegardés\n\r$heuexec:$minexec:$secexec/$heutotal:$mintotal:$sectotal\tAvSpeed : $AvSpeed Mo/s ; Speed : $ReSpeed Mo/s\n\r$pt> $p%\r";
	fi
	time=$(${EXPR} $time + 1);
	NR=`${PS} -A | ${GREP} rsync`;
#	if [ "X$NR" == "X" ]; then
#		ERR=1;
#		${ECHO} '';
#		break;
#	fi
	${SLEEP} 1;
done
${ECHO} '';
}


function usage ()
{
	${ECHO} "
Usage:

${script}	[-d|--dest-dev device | -l|--label device_label] 
		[-D|--dest-dir destination_directory]
		[-s|--src source]

${script}	[-h|--help]


Explanation:

device:			a partition device.
device_label:		a partition device named by label.
destination_directory:	a valid directory (can't be on Root partition).
source:			a valid directory (defaulted to /home).



Example:

 ${script} -s /home/USERNAME -l MyBackup
 ${script} -s /home/USERNAME -d /dev/sdb2
 ${script} -s /home/USERNAME -D /home/USERNAME/MyBackup
";
}



#
# Check if arguments are given
#
#if [ $# = 0 ] ; then
#	${ECHO} -e "Error: no arguments.\n\tType ${script} -h for help.";
#	Wait;
#	exit 1;
#fi


#
# Parsing arguments and options
#
TEMP=`${GETOPT} -o hs:d:D:l: --long help,src,dest-dev,dest-dir,label -n ${script} -- "$@"`
if [ $? != 0 ] ; then
	${ECHO} -e "Error parsing arguments and options\n\tType ${script} -h for more information";
	Wait;	
	exit 1;
fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "${TEMP}"
while true ; do
	case $1 in
		-d|--dest-dev)
			if [ ! -b $2 ]; then
				${ECHO} "Error: Option -d|--dest-dev requires a valid argument";
				Wait;				
				exit 1;
			fi
			DestDev="$2";
			DestLabel="";
			shift 2;;
		-D|--dest-dir)
			if [ ! -d $2 ]; then
				${ECHO} "Error: Option -D|--dest-dir requires a valid argument";
				Wait;				
				exit 1;
			fi
			DestDir="$2";
			DestLabel="";
			shift 2;;
		-l|--label)
			if [ -d $2 ] || [ -b $2 ]; then
				${ECHO} "Error: $2 is not a label. Option -l|--label requires a valid argument";
				Wait;				
				exit 1;			
			fi			
			case $2 in
				-*)
					${ECHO} "Error: Option -l|--label requires a valid argument";
					Wait;					
					exit 1;;
				*)
					DestLabel="$2";
					shift 2;;
			esac;;
		-s|--src)
			if [ ! -d $2 ]; then
				${ECHO} "Error: Option -s|--src requires a valid argument";
				Wait;
				exit 1;
			fi
			Src="$2";
			shift 2;;
		--)
			shift;
			break;;
		-h|--help)
			usage;			
			exit 0;;
		*)
			${ECHO} -e "Error: unrecognized option.\n\tType ${script} -h for more information";
			Wait;			
			exit 1;;
	esac
done

#
# Make sure we're running as root
#
if (( `${ID} -u` != 0 )); then
	${ECHO} "Error: must be root. Exiting...";
	Wait;	
	exit 1;
fi

#
# Testing if required parameter have not error
#

if [ -z "${Src}" ]; then
	${ECHO} -e "Error: Required parameter -s|--src \n\tType ${script} -h for more information.";
	Wait;	
	exit 1;
fi

if [ -z "${DestDev}" ] && [ -z "${DestDir}" ] && [ -z "${DestLabel}" ]; then
	${ECHO} -e "Error: Required parameter -d|--dest-dev device OR -D|--dest-dir directory OR -l|--label label \n\tType ${script} -h for more information.";
	Wait;	
	exit 1;
fi

if [ ! -z "${DestDev}" ] && [ ! -z "${DestDir}" ] || [ ! -z "${DestDev}" ] && [ ! -z "${DestLabel}" ] || [ ! -z "${DestDir}" ] && [ ! -z "${DestLabel}" ]; then
	${ECHO} -e "Error: Requiered only one of those parameter -d|--dest-dev device OR -D|--dest-dir directory OR -l|--label label \n\tType ${script} -h for more information.";
	Wait;
	exit 1;
fi

if [ ! -z ${DestDir} ]; then
	MountPoint=`${DF} -h ${DestDir} | ${GREP} / | ${AWK} '{ print $6 }'`;
	if [ "${MountPoint}" == "/" ]; then
		${ECHO} "Error: the destination directory can't be on Root partition \n\tType ${script} -h for more information.";
		Wait;
		exit 8;
	fi
fi

#
# Mounting device readwrite
#

if [ ! -z "${DestLabel}" ]; then
	${MKDIR} /Backup 2>/dev/null;	
	${MOUNT} -o rw,acl,user_xattr -L ${DestLabel} /Backup 2>/dev/null
	if [ $? -ne 0 ]; then
		${ECHO} "Trying to remount ${DestLabel} on /Backup readwrite..." 
		${CLEAR};
		${CAT} /var/log/${script}/inf;
		${MOUNT} -o remount,rw,acl,user_xattr -L ${DestLabel} /Backup 2>/dev/null
		if [ $? -ne 0 ]; then
			${ECHO} "Error: could not remount ${DestLabel} on /Backup readwrite";
			${RMDIR} /Backup;			
			Wait;			
			exit 32;
		fi
	fi
elif [ ! -z "${DestDev}" ]; then
	${MKDIR} /Backup 2>/dev/null;
	${MOUNT} -o rw,acl,user_xattr ${DestDev} /Backup 2>/dev/null
	if [ $? -ne 0 ]; then
		${ECHO} "Trying to remount ${DestDev} on /Backup readwrite..."
		${CLEAR};
		${CAT} /var/log/${script}/inf;
		${MOUNT} -o remount,rw,acl,user_xattr ${DestDev} /Backup 2>/dev/null
		if [ $? -ne 0 ]; then
			${ECHO} "Error: could not remount ${DestDev} on /Backup readwrite";
			${RMDIR} /Backup;			
			Wait;			
			exit 32;
		fi
	fi
elif [ ! -z "${DestDir}" ];  then
	${ECHO} "" >/dev/null;	
else
	${ECHO} "Error: could not mount backup device (bad parameters) OR backup destination directory not set";
	Wait;	
	exit 32;
fi

#
# Some infos to sdtout
#
if [ -z ${DestDir} ] && [ ! -z ${DestDev} ] || [ ! -z ${DestLabel} ]; then
	Size=`${DF} -h /Backup | ${GREP} /Backup | ${AWK} '{ print $4 }'`;
else
	DestWSl=`${ECHO} ${DestDir} | ${SED} -e "s/\/$//"`;	
	Size=`${DF} -h ${DestWSl} | ${GREP} / | ${AWK} '{ print $4 }'`;
fi
if [ -z ${DestDir} ]; then
	destback=/Backup/$backupname
else
	destback=${DestDir}/$backupname
fi
if [ -z ${DestDir} ] && [ ! -z ${DestDev} ]; then
	labb=`${BLKID} ${DestDev} |${AWK} '{print $2}' | ${SED} 's/^LABEL="\(.*\)"$/\1/'`
	devv=${DestDev}
elif [ -z ${DestDir} ] && [ ! -z ${DestLabel} ]; then
	devv=`${BLKID} -L ${DestLabel}`
	labb=${DestLabel}
fi
${ECHO} "
Source				=${Src}
Destination device		=$devv
Destination backup		=${destback}
Destination Label		=$labb
Free space on destination	=${Size}

Please don't use your computer during the backup...
" >>/var/log/${script}/inf;
${CLEAR};
${CAT} /var/log/${script}/inf;
#
# The real job
#
${MKDIR} /var/log/${script} 2>/dev/null;
${TOUCH} /var/log/${script}/error.log;
if [ ! -z "${DestLabel}" ] || [ ! -z "${DestDev}" ]; then
	BackupCount=`${LS} -1dt /Backup/backup.*/ 2>/dev/null| ${WC} -l`; # Check if a backup is already exist
	if [ ${BackupCount} -ne "0" ]; then
		LastBackup=`${LS} -1dt --sort none /Backup/backup.*/ | ${SED} 's/\/[A-Za-z]*\/\(backup.[0-9]*-[0-9]*-[0-9]*\)\//\1/g' | ${TAIL} -1`;
		LlastBackup=`${LS} -1dt --sort none /Backup/backup.*/ | ${SED} 's/\/[A-Za-z]*\/\(backup.[0-9]*-[0-9]*-[0-9]*\)\//\1/g' | ${TAIL} -2 | ${HEAD} -1`
		#if [ "${LastBackup}" == "${backupname}" ]; then # Check if a backup of this day is already exist			
		if [ -d /Backup/${backupname} ]; then # Check if a backup of this day is already exist			
			${ECHO} -en "The save ${backupname} already exist. Do you want to overwrite it [y/N/f]? : N\b";
			read ans;
			case ${ans:0:1} in
				o|O|y|Y)
					echo -e "Removing backup...";
					${RM} -fr /Backup/${backupname};
					LastBackup=`${LS} -1dt --sort none /Backup/backup.*/ 2>/dev/null| ${TAIL} -1`;;
				f|F)
					${ECHO} -en "Do you want to overwrite the backup of this day whith the last backup ($LlastBackup) [y/N]? : N\b";
					read ans2;
					case ${ans2:0:1} in
						o|O|y|Y)
							${ECHO} -e "Overwrite backup..."
							LastBackup=`${LS} -1dt --sort none /Backup/backup.*/ 2>/dev/null| ${TAIL} -2 | ${HEAD} -1`
							;;
						*)
							Notoverwrite=1
							LastBackup=`${LS} -1dt --sort none /Backup/backup.*/ 2>/dev/null| ${TAIL} -1`
							;;
					esac
					;;
				*)
					UmBackup;			
					Wait;					
					exit 0;;
			esac
		else
			LastBackup=`${LS} -1dt --sort none /Backup/backup.*/ 2>/dev/null| ${TAIL} -1`
		fi
		#${MKDIR} /Backup/${backupname} 2>/dev/null;
		if [[ ! -z ${LastBackup} && "${LastBackup}" != "/Backup/${backupname}/" && $Notoverwrite -ne 1 ]]; then # Copy the last backup to the new backup directory
			${CLEAR};
			${CAT} /var/log/${script}/inf;
			${ECHO} -e "Copying last backup $LastBackup..."
			#${LN} ${LastBackup}/ /Backup/${backupname};
			${CP} -alnf ${LastBackup} /Backup/${backupname};
			#ln -s ${LastBackup} /Backup/${backupname}/;
		fi
                ${MKDIR} /Backup/${backupname} 2>/dev/null;
	fi
	${CLEAR};
	${CAT} /var/log/${script}/inf;
	${ECHO} "Analysis of the directory..."
	savebefrs=`${DU} -xmsL /Backup/${backupname}/ 2>/dev/null| ${AWK} '{printf $1}'`;
	dsocbefrs=`${DF} -m | ${GREP} /Backup | ${AWK} '{print $3}'`;
	srcspaces=`${DU} -xms --exclude=/home/*/.gvfs --exclude=/Backup --exclude=/proc --exclude=/dev --exclude=/media ${Src} 2>/dev/null| ${AWK} '{printf $1}' | ${TR} -d G`;
	${ECHO} "Backup is in progress. Please wait..." >>/var/log/${script}/inf;
	${CLEAR};
	${CAT} /var/log/${script}/inf;
	datedeb=`${DATE} +%s`;
	#${RSYNC} --archive -z --compress-level=9 --hard-links --acls --fuzzy --delete --exclude=/Backup --exclude=/proc --exclude=/dev --exclude=/media --exclude=/home/*/.gvfs ${Src} /Backup/${backupname}/ 2>/var/log/${script}/error.log & # Make backup on device
	${RSYNC} --archive --hard-links --acls --fuzzy --delete --exclude=/Backup --exclude=/proc --exclude=/dev --exclude=/media --exclude=/home/*/.gvfs ${Src} /Backup/${backupname}/ 2>/var/log/${script}/error.log & # Make backup on device
	percent /Backup $savebefrs $dsocbefrs $srcspaces $datedeb;
	if [[ $? -ne 0 || $ERR == 1 ]]; then
		RsyncErr;		
		if [ ${Full} -eq 1 ]; then		
			${RM} -fr /Backup/${backupname}/;
			UmBackup;			
			Wait;			
			exit 16;		
		else
			UmBackup;
			Wait;			
			exit 16;
		fi	
	fi
	UmBackup;
elif [ ! -z "${DestDir}" ]; then
	BackupCount=`${LS} -1dt ${DestDir}/backup.*/ 2>/dev/null| ${WC} -l`; # Check if a backup is already exist
	if [ ${BackupCount} -ne "0" ]; then
		LastBackup=`${LS} -1dt --sort none ${DestDir}/backup.*/ | ${SED} 's/\/[A-Za-z]*\/\(backup.[0-9]*-[0-9]*-[0-9]*\)\//\1/g' | ${TAIL} -1`;
		LlastBackup=`${LS} -1dt --sort none ${DestDir}/backup.*/ | ${SED} 's/\/[A-Za-z]*\/\(backup.[0-9]*-[0-9]*-[0-9]*\)\//\1/g' | ${TAIL} -2 | ${HEAD} -1`
		#if [ "${LastBackup}" == "${backupname}" ]; then # Check if a backup of this day is already exist
		if [ -d ${DestDir}/${backupname} ]; then # Check if a backup of this day is already exist			
			${ECHO} -en "The save ${backupname} already exist. Do you want to overwrite it [y/N/f]? : N\b";
			read ans;
			case ${ans:0:1} in
				o|O|y|Y)
					${ECHO} -e "Removing backup..."
					${RM} -fr ${DestDir}/${backupname}/;
					LastBackup=`${LS} -1dt --sort none ${DestDir}/backup.*/ 2>/dev/null| ${TAIL} -1`;;
				f|F)
					${ECHO} -en "Do you want to overwrite the backup of this day whith the last backup ($LastBackup) [y/N]? : N\b";
					read ans2;
					case ${ans2:0:1} in
						o|O|y|Y)
							${ECHO} -e "Overwrite backup..."
							LlastBackup=`${LS} -1dt --sort none ${DestDir}/backup.*/ 2>/dev/null| ${TAIL} -2 | ${HEAD} -1`
							;;
						*)
							Notoverwrite=1
							LastBackup=`${LS} -1dt --sort none ${DestDir}/backup.*/ 2>/dev/null| ${TAIL} -1`;
							;;
					esac
					;;
				*)			
					Wait;					
					exit 0;;
			esac
		else
			LastBackup=`${LS} -1dt --sort none ${DestDir}/backup.*/ 2>/dev/null| ${TAIL} -1`
		fi
		#${MKDIR} ${DestDir}/${backupname} 2>/dev/null;
		if [[ ! -z ${LastBackup}  &&  "${LastBackup}" != "${DestDir}/${backupname}/" && $Notoverwrite -ne 1 ]]; then # Copy the last backup to the new backup directory
			${CLEAR};
			${CAT} /var/log/${script}/inf;
			${ECHO} -e "Copying last backup $LastBackup..."
			#${LN} ${LastBackup}/ ${DestDir}/${backupname};
			${CP} -alnf ${LastBackup} ${DestDir}/${backupname};
			#ln -s ${LastBackup} /Backup/${backupname}/;
		fi
                ${MKDIR} ${DestDir}/${backupname} 2>/dev/null;
	fi
	${CLEAR};
	${CAT} /var/log/${script}/inf;
	${ECHO} "Analysis of the directory..."
	srcspaces=`${DU} -xms --exclude=/home/*/.gvfs --exclude=/Backup --exclude=/proc --exclude=/dev --exclude=/media ${Src} 2>/dev/null| ${AWK} '{printf $1}' | ${TR} -d G`;
	savebefrs=`${DU} -xmsL ${DestDir}/${backupname}/ 2>/dev/null| ${AWK} '{printf $1}'`;
	dsocbefrs=`${DF} -m | ${GREP} ${DestDir} | ${AWK} '{print $3}'`;
	${ECHO} "Backup is in progress. Please wait..." >>/var/log/${script}/inf;
	${CLEAR};
	${CAT} /var/log/${script}/inf;
	datedeb=`${DATE} +%s`;
	#${RSYNC} --archive -z --compress-level=9 --hard-links --acls --fuzzy --delete --exclude=${DestDir}/${backupname}/ --exclude=/proc --exclude=/dev --exclude=/media --exclude=/home/*/.gvfs ${Src} ${DestDir}/${backupname}/ 2>/var/log/${script}/error.log & # Make backup on directory
	${RSYNC} --archive --hard-links --acls --fuzzy --delete --exclude=${DestDir}/${backupname}/ --exclude=/proc --exclude=/dev --exclude=/media --exclude=/home/*/.gvfs ${Src} ${DestDir}/${backupname}/ 2>/var/log/${script}/error.log & # Make backup on directory
	percent ${DestDir} $savebefrs $dsocbefrs $srcspaces $datedeb;
	if [ $? -ne 0 ]; then
		RsyncErr;
		if [[ ${Full} -eq 1 || $ERR == 1 ]]; then	
			${RM} -fr ${DestDir}/${backupname};			
			Wait;			
			exit 16;		
		else
			Wait;			
			exit 16;
		fi
	fi
fi

${ECHO} "End whithout errors";
Wait;
exit 0;

Dernière modification par Havany (Le 25/09/2010, à 16:12)

Hors ligne

Haut de page ↑