Make "Timeshift" like snapshots of your home-dir with hard-links to previous backup

Forum rules
Before you post please read how to get help
Post Reply
TI58C
Level 4
Level 4
Posts: 354
Joined: Tue Jul 18, 2017 5:57 am

Make "Timeshift" like snapshots of your home-dir with hard-links to previous backup

Post by TI58C » Mon Aug 05, 2019 8:20 am

Why ?
* Much faster than ordinary (g)rsync backup
* Saves a lot of disk-space

How does it work ?

In the first line of the script, change "dest_base=/media/rob/backups/home_rotate/" to your own backup directory. Make the script executable.

Each time you run "home_snapshot", a subdirectory with name according to template YYYY_MM_dd_hh_mm_ss is created in your backup-directory. This is an exact copy of your home-dir at the time the name/timestamp indicates.

If there is an earlier subdirectory with a name like YYYY_MM_dd_hh_mm_ss, rsync will create hard-links to that directory for unchanged files instead of writing the file to the new backup again. This saves time and disk-space.

Script will keep 10 snapshots (max_nr_of_backups=10), discarding the oldest if you make more. Number of snapshots to keep is easily changed in script.

Rsync options shamelessly copied from grsync (see them in grsync with Alt+r) with options:
Basic options
- preserve time
- preserve owner
- preserve permissions
- preserve group
- verbose
- do not leave filesystem
- show transfer progress
Advanced options
- Copy symlinks as symlinks
- Copy hardlinks as hardlinks
- protect remote args

Just added --itemize-changes --log-file and --link-dest options

Tip: if you use ncdu (ncurses disk usage, apt-get install ncdu), you can easily see which files were hard-linked (H at beginning of line). And much more.

Would very much appreciate your comments

Robert /TI58C

Code: Select all

#!/bin/bash

dest_base=/media/rob/backups/home_rotate/              # Change this directory to your own backup-dir. Mind the "/" at the end!
                                                       # Backup(s) will be in subdir(s) of this directory with name like YYYY_MM_dd_hh_mm_ss
max_nr_of_backups=10                                   # Set max nr of backups to keep.

src=/home/$USER/
now=$(date +%Y_%m_%d_%H_%M_%S)
dest="$dest_base""$now"/
echo -e "This directory is an rsync backup of source-dir : ""$src""\nmade at : ""$now""\nin target_dir : ""$dest" > "$src"000_____BACKUP_INFO_____.txt
rm -f rsync_log1
previous=$(ls -l "$dest_base" | awk '/^d/ && $9~/20[1-9][0-9]_[01][0-9]_[0-3][0-9]_[0-5][0-9]_[0-5][0-9]_[0-5][0-9]/ {print $9}' | sort)
if [ -z "$previous" ]                                                 
then
#  we do not have previous backup, do straightforward rsync
   rsync -rtpogxvlHs --progress --itemize-changes --log-file=rsync_log1 $src $dest
else
   # we do have previous backup(s)
   act_nr_of_backups=$(wc -l <<< "$previous")
   if [ "$act_nr_of_backups" -eq "$max_nr_of_backups" ]
   then
      # delete the oldest subdir (=first line in variable $previous).
      oldest_backup=$(head -n1 <<<"$previous")
      rm -rf "$dest_base""$oldest_backup"
   fi
   # use last backup dir to build hard-links from (=last line in variable $previous).
   last_backup=$(tail -n1 <<<"$previous")
   link_dest="$dest_base""$last_backup"
   # do an rsync backup, using previous backup directory to build hard-links for files that are unchanged. Saves a lot of space and is very fast !
   rsync -rtpogxvlHs --progress --itemize-changes --log-file=rsync_log1 --link-dest=$link_dest $src $dest
fi
rm -f "$src"000_____BACKUP_INFO_____.txt
xdg-open rsync_log1
exit
Linux is like my late labrador lady-dog: loyal and loving if you treat her lady-like, disbehaving princess if you don't.

Post Reply

Return to “Scripts & Bash”