Objectifs
- Créer un script de sauvegarde réutilisable et configurable.
- Archiver et compresser un dossier avec
tar. - Nommer les sauvegardes avec la date pour une meilleure organisation.
- Mettre en place une politique de rétention simple pour ne pas saturer l’espace disque.
- Aborder le chiffrement d’une sauvegarde pour la sécurité.
Le Scénario
Vous avez un dossier important sur votre serveur (par exemple, /var/www/mon_site) et vous voulez automatiser sa sauvegarde quotidienne dans un dossier de destination (par exemple, /mnt/backups). Chaque sauvegarde doit être datée, compressée, et vous ne voulez conserver que les 7 dernières.
Les Outils à Combiner
tar: Pour créer l’archive.date: Pour générer un nom de fichier unique et horodaté.find: Pour trouver et supprimer les anciennes sauvegardes.- Un squelette de script robuste avec gestion d’arguments et d’erreurs.
gpg(en option) : Pour le chiffrement.
Le Script Complet
Voici un script complet et commenté qui réalise cette tâche.
#!/usr/bin/env bash
# Mode strict
set -euo pipefail
# --- Documentation et Constantes ---
# Description:
# Crée une archive .tar.gz compressée d'un dossier source
# vers un dossier de destination, et applique une rotation.
#
# Usage:
# ./backup.sh -s <dossier_source> -d <dossier_destination> [-k <jours>]
#
# Options:
# -s <source> Dossier à sauvegarder (obligatoire).
# -d <dest> Dossier où stocker les sauvegardes (obligatoire).
# -k <jours> Nombre de jours de rétention (optionnel, 7 par défaut).
# -h Affiche cette aide.
readonly SCRIPT_NAME="$(basename "$0")"
# --- Fonctions ---
die() {
echo >&2 "[ERREUR] $@"
exit 1
}
usage() {
echo "Usage: $SCRIPT_NAME -s <source> -d <dest> [-k <jours>]"
echo " Crée une sauvegarde compressée avec rotation."
exit 0
}
# --- Fonction Principale ---
main() {
local SOURCE_DIR=""
local DEST_DIR=""
local RETENTION_DAYS=7
while getopts ":hs:d:k:" opt; do
case "$opt" in
h) usage ;;
s) SOURCE_DIR="$OPTARG" ;;
d) DEST_DIR="$OPTARG" ;;
k) RETENTION_DAYS="$OPTARG" ;;
\?|:) die "Option invalide ou argument manquant. Utilisez -h pour l'aide." ;;
esac
done
shift $((OPTIND - 1))
# --- Validation ---
if [[ -z "$SOURCE_DIR" || -z "$DEST_DIR" ]]; then
usage
fi
if [[ ! -d "$SOURCE_DIR" ]]; then
die "Le dossier source '$SOURCE_DIR' n'existe pas."
fi
if [[ ! -d "$DEST_DIR" ]]; then
# On peut décider de le créer s'il n'existe pas
echo "Le dossier de destination '$DEST_DIR' n'existe pas, création..."
mkdir -p "$DEST_DIR"
fi
# --- Logique Principale ---
local DATE_TAG
DATE_TAG=$(date +"%Y-%m-%d_%H%M%S")
# On utilise 'basename' pour n'avoir que le nom du dossier source, pas son chemin
local BASENAME_SOURCE
BASENAME_SOURCE=$(basename "$SOURCE_DIR")
local ARCHIVE_NAME="backup-${BASENAME_SOURCE}-${DATE_TAG}.tar.gz"
local DEST_FILE="${DEST_DIR}/${ARCHIVE_NAME}"
echo "Création de la sauvegarde : '$DEST_FILE'..."
# c: create, z: gzip, f: file
# L'option -C permet de se "déplacer" dans un dossier avant d'archiver,
# ce qui évite d'avoir toute l'arborescence dans le .tar.gz
tar -czf "$DEST_FILE" -C "$(dirname "$SOURCE_DIR")" "$BASENAME_SOURCE"
echo "Sauvegarde terminée avec succès."
# --- Chiffrement (Optionnel) ---
# Si gpg est installé et configuré
# gpg -c --batch --passphrase "VOTRE_MOT_DE_PASSE_SECRET" -o "${DEST_FILE}.gpg" "$DEST_FILE"
# if [[ $? -eq 0 ]]; then
# rm "$DEST_FILE" # Supprimer l'archive non chiffrée si le chiffrement a réussi
# echo "Archive chiffrée."
# fi
# --- Rotation des sauvegardes ---
echo "Application de la politique de rétention (${RETENTION_DAYS} jours)..."
# Trouve les fichiers .tar.gz dans le dossier de destination qui ont été modifiés
# il y a plus de RETENTION_DAYS jours, et les supprime.
find "$DEST_DIR" -type f -name "backup-*.tar.gz" -mtime "+$RETENTION_DAYS" -delete
echo "Rotation terminée."
}
# --- Point d'entrée ---
main "$@"
Bonnes Pratiques Mises en Œuvre
- Script configurable : L’utilisation de
getoptsrend le script flexible et réutilisable. - Noms de fichiers clairs : L’horodatage permet de savoir immédiatement quand une sauvegarde a été faite et de les trier.
- Validation des entrées : Le script vérifie que les dossiers existent avant de commencer, ce qui évite les erreurs en cours de route.
- Gestion de la rétention : L’utilisation de
findavec-mtimeet-deleteest une manière standard et efficace de gérer la rotation des backups.
Pièges Évités
- Chemins dans l’archive : L’utilisation de
tar -Cpermet de créer une archive “propre” qui contient directement le dossier sauvegardé, et non tout son chemin depuis la racine/. - Erreurs silencieuses : Grâce à
set -e, sitaréchoue, le script s’arrêtera et n’affichera pas le message de succès.
Exercices
-
Tester le script :
- Créez un dossier
mon_dossier_testavec quelques fichiers à l’intérieur. - Créez un dossier
destination_backups. - Lancez le script pour sauvegarder
mon_dossier_testdansdestination_backups. - Vérifiez que l’archive a bien été créée.
- Créez un dossier
-
Ajouter des logs :
- Modifiez le script pour qu’il écrive ses messages (
echo) à la fois dans le terminal et dans un fichier de log (ex:/var/log/backup.log). - Indice : vous pouvez utiliser la commande
tee -a.
- Modifiez le script pour qu’il écrive ses messages (
-
Tester la rotation :
- Créez manuellement plusieurs fausses archives dans votre dossier de destination avec des dates de modification différentes en utilisant la commande
touch. - Ajustez la rétention (
-k) à 1 ou 2 jours et lancez le script (même s’il ne fait pas de nouvelle sauvegarde) pour vérifier que les anciennes archives sont bien supprimées.
- Créez manuellement plusieurs fausses archives dans votre dossier de destination avec des dates de modification différentes en utilisant la commande