#!/bin/bash # This script performs an incremental backup of the specified source directory, # generates CRC32 checksums for only the files that are backed up or modified, # and manages the deletion of old backups. The CRC32 checksum files are stored # in a dedicated subdirectory within the backup directory. You can also run the # script with the 'verification' argument to check the integrity of only the files # processed in the latest backup. # # NOTE: This script is not tested and is intended for debugging purposes. Use with caution. # Configuration SOURCE_DIR="/chemin/vers/votre/dossier_source" # Replace with the path to your source directory BACKUP_DIR="/chemin/vers/votre/dossier_backup" # Replace with the path to your backup directory LOG_FILE="/chemin/vers/votre/fichier_log" # Replace with the path to your log file RETENTION_PERIOD=60 # Number of days to retain deleted/modified files (2 months) EMAIL="votre_email@example.com" # Replace with your email address CRC_RETENTION_PERIOD=60 # Number of days to retain CRC checksum files # Directory for CRC32 checksums within the backup directory CRC_DIR="$BACKUP_DIR/.crc_checksums" mkdir -p "$CRC_DIR" # Create the checksum directory if it does not exist # Files for CRC32 checksums SOURCE_CRC_FILE="$CRC_DIR/source_crc_checksums.txt" BACKUP_CRC_FILE="$CRC_DIR/backup_crc_checksums.txt" # Temporary files for CRC32 checksums of the current backup CURRENT_BACKUP_CRC_FILE="$CRC_DIR/current_backup_crc_checksums.txt" # Function to send an email in case of error send_error_email() { SUBJECT="Backup Error on $(hostname)" MESSAGE="An error occurred during the backup on $(hostname) at $(date +'%Y-%m-%d %H:%M:%S'). Please check the log file at $LOG_FILE for details." echo "$MESSAGE" | mail -s "$SUBJECT" "$EMAIL" } # Function to log actions to the log file and send an email in case of error log_action() { echo "$(date +'%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" if [[ "$1" == "ERREUR"* ]]; then send_error_email fi } # Check if the source and backup directories exist if [ ! -d "$SOURCE_DIR" ]; then log_action "ERREUR : The source directory '$SOURCE_DIR' does not exist." exit 1 fi if [ ! -d "$BACKUP_DIR" ]; then log_action "The backup directory '$BACKUP_DIR' does not exist. Creating directory." mkdir -p "$BACKUP_DIR" if [ $? -ne 0 ]; then log_action "ERREUR : Unable to create the backup directory '$BACKUP_DIR'." exit 1 fi fi # Function to generate CRC32 checksums only for files processed in the current backup generate_crc_checksums() { # Generate checksums for source files find "$SOURCE_DIR" -type f -exec crc32 {} \; > "$SOURCE_CRC_FILE" if [ $? -ne 0 ]; then log_action "ERREUR : Unable to generate CRC32 checksums for the source directory." exit 1 fi # Generate checksums for files in the backup directory find "$BACKUP_DIR" -type f ! -path "$CRC_DIR/*" -exec crc32 {} \; > "$CURRENT_BACKUP_CRC_FILE" if [ $? -ne 0 ]; then log_action "ERREUR : Unable to generate CRC32 checksums for the backup directory." exit 1 fi } # Function to verify the integrity of files processed in the latest backup verify_integrity() { if [ ! -f "$SOURCE_CRC_FILE" ] || [ ! -f "$CURRENT_BACKUP_CRC_FILE" ]; then log_action "ERREUR : Checksum files do not exist. Run the script without arguments to generate them." exit 1 fi # Compare the checksums and store differences diff "$SOURCE_CRC_FILE" "$CURRENT_BACKUP_CRC_FILE" > /tmp/diff_output.txt if [ $? -eq 0 ]; then echo "La vérification de l'intégrité des fichiers a terminé avec succès." log_action "Backup integrity has been successfully verified." else log_action "ERREUR : Backup integrity check failed. Differences found between source and backup checksums." # Print the errors with file paths while IFS= read -r line; do echo "$line" done < /tmp/diff_output.txt exit 1 fi } # Function to clean up old CRC32 checksum files cleanup_old_crc_files() { find "$CRC_DIR" -type f -mtime +$CRC_RETENTION_PERIOD -exec rm -f {} \; if [ $? -ne 0 ]; then log_action "ERREUR : Unable to delete old CRC32 checksum files." exit 1 fi } # If the 'verification' argument is provided, only perform the verification if [ "$1" == "verification" ]; then verify_integrity exit 0 fi # Incremental backup with error handling # This section performs the incremental backup of the source directory to the backup directory # Deleted files are moved to a dated subdirectory. The checksum directory is excluded from the backup. rsync -av --delete --backup --backup-dir="$BACKUP_DIR/deleted/$(date +'%Y-%m-%d')" --exclude "$CRC_DIR/" "$SOURCE_DIR/" "$BACKUP_DIR/" if [ $? -ne 0 ]; then log_action "ERREUR : The incremental backup failed." exit 1 fi # Generate CRC32 checksums for the files processed in the latest backup generate_crc_checksums # Verify the integrity of the files processed in the latest backup verify_integrity # Delete old backups of deleted/modified files find "$BACKUP_DIR/deleted" -type d -mtime +$RETENTION_PERIOD -exec rm -rf {} \; if [ $? -ne 0 ]; then log_action "ERREUR : Unable to delete old backups." exit 1 fi # Clean up old CRC32 checksum files cleanup_old_crc_files log_action "Incremental backup completed successfully."