La sauvegarde est la base de tout ! Oui, oui :)
Si cette phrase ne vous parle pas, alors je croise les doigts pour ne pas que cela vous arrive : perdre toutes vos données.

Faites des sauvegardes partout, où vous voulez, sur n'importe quel support ; tant que vos données sont répliquées quelque part, alors c'est une situation encore vivable. Si elles sont chiffrées, c'est encore mieux.
J'en fais des caisses, mais il ne faut pas sous-estimer l'importance de la chose.

Alors de mon côté, j'utilise un disque dur externe que je branche spécialement pour l'occasion et sur lequel se trouvent 3 fichiers et un dossier :

  1. Le dossier sav dans lequel les données seront copiées/mises à jour.
  2. Le fichier exclusions.lst, un simple fichier texte contenant une liste des fichiers à exclure de la sauvegarde.
  3. Le fichier sauvegarder.sh, un simple script bash qui gère la sauvegarde.
  4. Le fichier sources.lst, un simple fichier texte contenant une liste des chemins à sauvegarder.

Les fichiers de configuration

exclusions.lst :

*eden/data/*

sources.lst :

# Courriels + autres
/mnt/master/perso/

# Sites web
/mnt/master/www/

# Projets
/mnt/master/projets/
/mnt/stock/projets/
/mnt/stock/programmation/

# Autres
/home/tiger-222/Documents/
/home/tiger-222/Images/
/mnt/stock/images/

Le script de sauvegarde

Le script utilise Zenity, un framework permettant de créer des boîtes de dialogue. S'il n'y avait que 3 choses à retenir, elles seraient :

  1. Zenity lit les données à partir de l'entrée standard, ligne par ligne.
  2. Si une ligne commence par #, le message est mis à jour avec le texte suivant ce caractère.
  3. Si une ligne contient seulement un nombre, le pourcentage est mis à jour avec ce nombre.

Commençons par définir les constantes :

SRC="/"
DST="sav/"
FILES="$(date '+%Y-%m').lst"
Z_OPTS="--title=Sauvegarde --width=460"
START="$(date '+%H:%M')"

Ensuite, le script se compose de 3 fonctions.

dry_run(), qui lance la synchronisation sans modifier quoi que ce soit. Le but de cette fonction est de calculer le nombre de fichiers qui seront mis à jour. Une liste des fichiers à traiter sera ensuite crée.

dry_run() {
    local opt="-rmnvzLS --size-only --exclude-from=exclusions.lst --files-from=sources.lst"
    local num=0

    while read -r line; do
        (( num += 1 ))
        echo "# Détermination des documents à sauvegarder : ${num}"
        echo "${line}" >> "${FILES}"
    done < <(rsync ${opt} "${SRC}" "${DST}") > >(zenity ${Z_OPTS} \
            --progress \
            --pulsate \
            --auto-close \
            --text "Détermination des documents à sauvegarder...")

    if [ ${num} -eq 3 ]; then
        sleep 2
        echo "Tout est à jour !"
        rm "${FILES}"
        exit 0
    fi

    head "${FILES}" --lines=-3 > "${FILES}.tmp"
    mv -f "${FILES}.tmp" "${FILES}"
}
Capture d'écran n°1

backup() synchronise les fichiers en se basant sur la liste générée par dry_run() :

backup() {
    local opt
    local text
    local total

    opt="--out-format='%n' --files-from=${FILES}"
    total="$(wc -l "${FILES}" | cut -d' ' -f1)"

    rsync ${opt} "${SRC}" "${DST}" | \
        while read -r line; do
            (( num += 1 ))
            percent=$(( num * 100 / total ))
            echo ${percent}--blocking-io
            echo "#${percent}% (${num}/${total}) ${SRC}${line:1:69}..."
        done | zenity ${Z_OPTS} --progress --auto-close

    case $? in
        0)
            text="\nSauvegarde terminée !\nTemps : ${START} -> $(date '+%H:%M')"
            zenity ${Z_OPTS} --info --text="${text}"
            ;;
        *) zenity ${Z_OPTS} --error --text="\nSauvegarde annulée." ;;
    esac
}
Capture d'écran n°2

main() est la fonction qui gère l'ordre des appels :

main() {
    [ -d "${DST}" ] || mkdir "${DST}"
    [ -f "${FILES}" ] && rm "${FILES}"

    dry_run
    backup
}

Historique

  • 2018-06-02 : Décomposition en fonctions et explications plus claires.
  • 2015-11-21 : Quelques ajustement mineurs.