Skip to main content

Rsync backup script

Summary

Simple bash shell script which uses rsync to back up the user home directory (~/) to backup mountpoint, e.g. a hard drive, thumb drive, sd card, etc. Verifies mountpoint exists, writes complete rsync log to mountpoint.

Introduction #

Creating reliable backups is a critical part of managing data, whether for personal use or professional environments. In this article I would like to share a bash script that leverages the power of rsync to back up the user’s home directory (/home/user) to a designated backup location (/media/user/backup). While the example provided uses a local backup location, rsync is equally effective for remote backups, offering versatility and robustness.

Rsync is an excellent tool for backups because it is:

The script not only simplifies the backup process but also adds features like error handling, log management, and user feedback to ensure transparency and ease of use.

Shell Backup Script with Rsync #

Want to contribute? Visit the Rsync Backup Script repository on GitHub.

This bash shell script is designed to back up the user’s home directory ($HOME) to a specified backup location (/media/user/backup). The backup location could be remote, for this example, I will keep it local.

#!/bin/bash

# ERROR HANDLING
# e - script stops on error (return != 0)
# u - error if undefined variable
# o pipefail - script fails if one of piped command fails
# x - output each line (debug)
set -euo pipefail

__ScriptVersion="1.2"

#===  FUNCTION  ================================================================
#         NAME:  Backup ~/
#  DESCRIPTION:  Backs up the user home directory to backup mountpoint.
#===============================================================================
function usage ()
{
    echo "Usage :  $0 [options] [--]
    Options:
    -h|help       Make sure backup destination is mounted.
    -v|version    Display script version"

}    # ----------  end of function usage  ----------


# Variables
#
# source directory to back up
backuppath=$HOME

# back up destination location
# Arch
#mountpoint="/run/media/user/backup"
# Ubuntu
mountpoint="/media/user/backup"

# Current date in YYYY-MM-DD
date=$(date +%Y-%m-%d)

# Current time in HH:MM:SS
time=$(date +%T)

# Check if back up disk is mounted
if mountpoint -q $mountpoint
then


# Clean up previous log(s)
if [ ! -f $mountpoint/backup*.txt ]; then
    echo "No backup file(s) found!"
    else
    echo -e "Confirm deletion: press y\nCancel deletion: press n"
    rm -i $mountpoint/backup*.txt
fi

# Rsync Back Up
#
rsync \
  -avr \
  --delete \
  --progress \
  --stats \
  --itemize-changes \
  --exclude '.cache/' \
  $backuppath \
  $mountpoint \
  2>&1 | tee $mountpoint/backup-log_$date-$time.txt # writing log
  
  # Confirmation message
  #
  # echo -e - escaped strings will be interpreted
  # \033 - beginning/ending of the style
  # m - end of the sequence
  # [0m - resets all attributes, e.g. colors, formatting, etc.
  # \n - newline
  #
  # Sequence integers:
  #
  # 0 - Normal Style
  # 1 - Bold
  # 4 - Underlined
  echo -e "\n\n  \033[4mSUCCESS\033[0m\n\n  \033[1m$backuppath\033[0m\n    has been synced to\n  \033[1m$mountpoint\033[0m\n\n"
  
  # Print latest file to back up drive (manual plausability check)
  echo -e "Latest file written to back up drive:"
  find $mountpoint -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1
  
  # Wait for 15 seconds
  sleep 15

  # Clear the screen
  clear
  
  # Success exit code
  exit 0

# If $mountpoint is not mounted
else
   echo -e "\033[1m$mountpoint\033[0m is not mounted"   
   # Print error exit code -  No such device or address
  exit 6
fi

This script automates the process of backing up the user’s home directory to a mounted backup destination. It includes error handling, logging, file cleanup, and user feedback to ensure reliable and transparent operation.

Step-by-Step Explanation of the Script #

Preliminaries #

  1. Set strict error handling:
    The set -euo pipefail ensures:
    • -e: The script exits if any command returns a non-zero exit code.
    • -u: Exiting with an error if an undefined variable is used.
    • -o pipefail: The script fails if any command in a pipeline fails.
  2. Define script metadata:
    __ScriptVersion=”1.2” defines the version of the script.

  3. Define a usage function:
    The usage function describes how to run the script and explains the options:
    • -h|help: Ensures the backup destination is mounted.
    • -v|version: Displays the script version.

Set Key Variables #

Main Logic #

  1. Check if the backup destination is mounted:
    The script uses mountpoint -q $mountpoint to verify if the backup destination is mounted.
    • If mounted:
      Proceed with the backup process.
    • If not mounted:
      Display an error message:
      "$mountpoint is not mounted", styled in bold, and exit with code 6.
  2. Clean up old logs:
    Check if any backup log files exist at the destination (backup*.txt).
    • If none are found: Print "No backup file(s) found!".
    • If found: Prompt for confirmation (y to delete, n to cancel) and delete selected logs.
  3. Perform the backup using rsync:
    The script uses rsync with the following options:
    • -a: Archive mode (preserves symbolic links, permissions, etc.).
    • -v: Verbose output.
    • -r: Recursively sync directories.
    • --delete: Remove files from the destination that no longer exist in the source.
    • --progress: Show progress for each file.
    • --stats: Display transfer statistics.
    • --itemize-changes: List changes made during the sync.
    • --exclude '.cache/': Exclude the .cache/ directory.
    • Output from rsync is piped to tee, saving a log file named backup-log_<date>-<time>.txt at the backup destination.
  4. Display a success message:
    • Use styled and formatted text (\033 sequences) to indicate success.
    • Specify the synced source ($backuppath) and destination ($mountpoint).
  5. Print the latest file written to the backup destination:
    Use find to locate the most recently written file and display its timestamp.

  6. Wait, clear screen, and exit:
    • Pause for 15 seconds (sleep 15).
    • Clear the terminal (clear).
    • Exit with code 0 to signal success.

Error Handling #

If the backup destination ($mountpoint) is not mounted:

Create a Bash Alias #

Create a bash alias to simplify the backup command. Execute the backup with the short, memorable keyword backup:

  1. Move the Script to a Permanent Location:
    • Ensure the script is saved to a directory that is accessible and does not change, such as ~/scripts/backup.sh.
    • Make the script executable:
      chmod +x ~/scripts/backup.sh
  2. Edit the Bash Configuration File:
    Open your shell configuration file (~/.bash_aliases, ~/.bashrc, ~/.bash_profile, or ~/.zshrc depending on your shell) in a text editor. For example:
    vim ~/.bash_aliases

  3. Add an Alias for the Script:
    Add the following line at the end of the configuration file:
    alias backup='~/scripts/backup.sh'

  4. Reload (source) the Configuration File:
    After saving the file, reload it to apply the changes:
    source ~/.bash_aliases

  5. Use the Alias:
    You can now run the script simply by typing:
    backup

Further readings #

Sources and recommended, further resources on the topic:

Author

Jonas Jared Jacek • J15k

Jonas Jared Jacek (J15k)

Jonas works as project manager, web designer, and web developer since 2001. On top of that, he is a Linux system administrator with a broad interest in things related to programming, architecture, and design. See: https://www.j15k.com/

License

License: Rsync backup script by Jonas Jared Jacek is licensed under CC BY-SA 4.0.

This license requires that reusers give credit to the creator. It allows reusers to distribute, remix, adapt, and build upon the material in any medium or format, for noncommercial purposes only. To give credit, provide a link back to the original source, the author, and the license e.g. like this:

<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/"><a property="dct:title" rel="cc:attributionURL" href="https://www.ditig.com/publications/rsync-backup-script">Rsync backup script</a> by <a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://www.j15k.com/">Jonas Jared Jacek</a> is licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="license noopener noreferrer">CC BY-SA 4.0</a>.</p>

For more information see the DITig legal page.


“Learning from conventions will make your site better.”

Jeffrey Veen, American designer and design strategistThe Art & Science of Web Design, - IT quotes