DEV Community

Sourav kumar
Sourav kumar

Posted on

Day-04/100 - Automating Backups with Rsync: A Function-Based Bash Script with Rotation

Backups are crucial for data security and disaster recovery. Whether you're safeguarding personal files or managing production environments, automating backups reduces risk and ensures data integrity.

In this blog, we’ll explore an industry-standard Bash script for automated, incremental backups using rsync, following best practices such as:
✔ Function-based scripting for readability and reusability
✔ Efficient incremental backups using rsync
✔ Automated backup rotation (retaining only the last 3 backups)
✔ Error handling and logging for reliability

Why Use Rsync for Backups?
Unlike full backups (e.g., ZIP-based archives), rsync efficiently synchronizes only changed files, making it:

  1. Faster – Transfers only modified data
  2. Storage-efficient – Keeps incremental backups, saving disk space
  3. Versatile – Supports remote backups over SSH

The Rsync Backup Script
Below is a function-based industry-standard Bash script that automates incremental backups with a 3-day retention policy.

🔹 Script: backup_and_rotation_rsync.sh

#! /bin/bash

<< readme
This is an industry-standard script for incremental backups using rsync with a 3-day rotation.

Usage:
./backup_and_rotation_rsync.sh <path to your source> <path to backup folder>
readme

# Function to display usage information
function display_usage {
    echo "Usage: ./backup_and_rotation_rsync.sh <path to your source> <path to backup folder>"
}

# Check if the correct number of arguments is provided
if [ $# -ne 2 ]; then
    display_usage
    exit 1
fi

# Assign arguments to variables
source_dir=$1
backup_dir=$2
timestamp=$(date '+%Y-%m-%d-%H-%M-%S')
backup_target="${backup_dir}/backup_${timestamp}"
log_file="${backup_dir}/backup_${timestamp}.log"

# Function to check if rsync is installed
function check_rsync_installed {
    if ! command -v rsync > /dev/null 2>&1; then
        echo "Error: rsync is not installed. Please install it and try again." >&2
        exit 2
    fi
}

# Function to create a backup using rsync
function create_backup {
    mkdir -p "$backup_target"  # Ensure backup directory exists

    rsync -av --delete "$source_dir/" "$backup_target/" > "$log_file" 2>&1

    if [ $? -eq 0 ]; then
        echo "Backup completed successfully at $backup_target"
    else
        echo "Backup failed! Check log: $log_file" >&2
        exit 3
    fi
}

# Function to perform backup rotation (retain only the last 3 backups)
function perform_rotation {
    backups=("${backup_dir}"/backup_*)  # Find existing backups
    backups=($(ls -td "${backups[@]}" 2>/dev/null))  # Sort backups by timestamp (newest first)

    echo "Existing backups: ${backups[@]}"

    if [ "${#backups[@]}" -gt 3 ]; then
        echo "Performing rotation: Keeping latest 3 backups"

        backups_to_remove=("${backups[@]:3}")  # Keep latest 3 backups
        echo "Removing backups: ${backups_to_remove[@]}"

        for backup in "${backups_to_remove[@]}"; do
            rm -rf "${backup}"
        done
    fi
}

# Run the functions in order
check_rsync_installed
create_backup
perform_rotation
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Explanation
1️⃣ Argument Validation

if [ $# -ne 2 ]; then
    display_usage
    exit 1
fi
Enter fullscreen mode Exit fullscreen mode

The script requires two arguments:

  • Source directory – Folder to back up
  • Backup directory – Where backups will be stored
  • If not provided, it displays the correct usage and exits.

2️⃣ Checking Rsync Installation

function check_rsync_installed {
    if ! command -v rsync > /dev/null 2>&1; then
        echo "Error: rsync is not installed. Please install it and try again." >&2
        exit 2
    fi
}
Enter fullscreen mode Exit fullscreen mode

Since rsync is essential for this script, we check if it's installed. If not, an error message prompts the user to install it.

3️⃣ Creating the Backup

function create_backup {
    mkdir -p "$backup_target"  # Ensure backup directory exists

    rsync -av --delete "$source_dir/" "$backup_target/" > "$log_file" 2>&1
}
Enter fullscreen mode Exit fullscreen mode
  • rsync -av preserves permissions, timestamps, and symbolic links.
  • --delete removes files in the backup that no longer exist in the source.
  • Logs are saved for later review.

4️⃣ Backup Rotation (Keeping Only Last 3 Backups)

function perform_rotation {
    backups=("${backup_dir}"/backup_*)  
    backups=($(ls -td "${backups[@]}" 2>/dev/null))  # Sort backups by timestamp (newest first)

    if [ "${#backups[@]}" -gt 3 ]; then
        backups_to_remove=("${backups[@]:3}")  # Keep latest 3 backups
        for backup in "${backups_to_remove[@]}"; do
            rm -rf "${backup}"
        done
    fi
}
Enter fullscreen mode Exit fullscreen mode

This ensures only the latest 3 backups are retained by:
✅ Sorting backups by timestamp
✅ Keeping the latest 3
✅ Deleting older backups automatically

⏳ How to Use This Script

1️⃣ Make the script executable

chmod +x backup_and_rotation_rsync.sh
Enter fullscreen mode Exit fullscreen mode

2️⃣ Run the script with the source and backup folder paths

./backup_and_rotation_rsync.sh /home/user/documents /backups
Enter fullscreen mode Exit fullscreen mode

3️⃣ Check backup logs

cat /backups/backup_YYYY-MM-DD-HH-MM-SS.log
Enter fullscreen mode Exit fullscreen mode

Top comments (0)