Featured image of post Simple Incremental Bash Backup Script

Simple Incremental Bash Backup Script

A bash script to incrementally backup multiple different directories.

Introduction

While there are numerous backup solutions available for Linux, many require extensive configuration and maintenance, and restoring from the backup is not always simple. Incremental backups are ideal because they maintain snapshots of the files and allow for access to previous versions of files.

Linux Journal recently published an article on various backup solutions, and I thought I’d provide my incremental backup script that uses rsync and cp.

Incremental backup script

This script provides an incremental backup solution and only requires rsync and cp to be installed on the system.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/bin/bash

# Define the directories to backup and their destination directories
source_dir1="/source1"
backup_dir1="/backup1/"

source_dir2="/source2"
backup_dir2="/backup2/"

# Define excluded directories
excluded_dir1="leave/out/"
excluded_dir2="dont/want/"
excluded_dir3="exclude/this/"

# Function to run a backup
run_backup() {
  source_dir=$1
  backup_dir=$2

  # Check if the source directory exists
  if [ ! -d "$source_dir" ]; then
    echo "Error: Source directory not found"
    exit 1
  fi

  # Input year and date
  echo "What is today's year:"
  read backup_year
  echo "What is today's date:"
  read backup_date

  # Check if the backup directory exists and run backup
  if [ -d "$backup_dir" ]; then
    echo "Backup directory found, backing up $source_dir"
    rsync -av --delete --exclude "$excluded_dir1" --exclude "$excluded_dir2" --exclude "$excluded_dir3" $source_dir $backup_dir/Monthly/
    cp -al $backup_dir/Monthly/ $backup_dir/$backup_year/$backup_date/
  else
    echo "Error: Backup directory not found"
    exit 1
  fi
}

# Run backups
run_backup $source_dir1 $backup_dir1
run_backup $source_dir2 $backup_dir2

# Output confirmation
echo "Backup complete"

Let’s break this down line by line.

Source and backup directories

First, we need to define the source and backup directories, and any directories from the source that are to be excluded from the backup:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Define the directories to backup and their destination directories
source_dir1="/source1"
backup_dir1="/backup1/"

source_dir2="/source2"
backup_dir2="/backup2/"

# Define excluded directories
excluded_dir1="leave/out/"
excluded_dir2="dont/want/"
excluded_dir3="exclude/this/"

You can add as many directories as you want here.

Backup function

Then we have the backup function. This performs the following:

  1. Takes an input of the source and backup directories (defined above)
  2. Checks to see if the source directory exists
  3. Prompts for a year
  4. Prompts for a date
  5. Checks to make sure the backup destination directory exists
  6. Executes the backup
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Function to run a backup
run_backup() {
  source_dir=$1
  backup_dir=$2

  # Check if the source directory exists
  if [ ! -d "$source_dir" ]; then
    echo "Error: Source directory not found"
    exit 1
  fi

  # Input year and date
  echo "What is today's year:"
  read backup_year
  echo "What is today's date:"
  read backup_date

  # Check if the backup directory exists and run backup
  if [ -d "$backup_dir" ]; then
    echo "Backup directory found, backing up $source_dir"
    rsync -av --delete --exclude "$excluded_dir1" --exclude "$excluded_dir2" --exclude "$excluded_dir3" $source_dir $backup_dir/Monthly/
    cp -al $backup_dir/Monthly/ $backup_dir/$backup_year/$backup_date/
  else
    echo "Error: Backup directory not found"
    exit 1
  fi
}

rsync is used to compare the files in the source to the Monthly backup directory and then update or delete files accordingly.

Once the files are copied over via rsync, then the cp command is used to link the files in the Monthly directory to the year/date/ diorectory. As the files change in the Monthly directory, then the link also changes. This method saves disk space because files are not copied over and over again. Any files that do not change are simply linked within the filesystem. The links take up a trivial amount of disk space, and the filesystem handles all of the heavy lifting associated with tracking which files are linked and where on the filesystem. There is no database, log, etc. required to track the individual files and/or their versions.

Running backups

Finally, run the backups and confirm complete:

1
2
3
4
5
6
# Run backups
run_backup $source_dir1 $backup_dir1
run_backup $source_dir2 $backup_dir2

# Output confirmation
echo "Backup complete"

Results

This script provides an incremental backup record organized by year and date:

Backup directory

Year subdirectory

Accessing older backups is straightforward - simply navigate to the desired directory within the filesystem.

Deleting old backups

Deleting or removing old and out-of-date backups is as simple as deleting the directories. The filesystem links and files that are not linked elsewhere are removed from the filesystem, freeing up the disk space.

References

https://rsync.samba.org/
https://github.com/WayneD/rsync
https://www.gnu.org/software/coreutils/
https://www.man7.org/linux/man-pages/man1/cp.1.html

Licensed under CC BY-NC-SA 4.0
Last updated on September 23, 2024
Built with Hugo
Theme Stack designed by Jimmy