draft0 - a shared blog by just some people

Menu

backup.sh

This entry is an update of the entry 'Backup Shell Script'.

I've updated/improved my backup script again.

Download


#!/bin/bash
#2021-11-03

budir="/mnt/backup"
num=8
list="/root/backup-list"
hostname=$(</etc/hostname)
srcdir="$1"
#NAME=${SRCDIR//\//--}
name="$2"

function usage () {
  echo "This script requires either one or two arguments."
  echo "Usage:"
  echo "$0 JOBLIST"
  echo "$0 SOURCE_DIRECTORY NAME"
  echo
  echo "JOBLIST File that contains one backup job per line in the format SOURCE_DIRECTORY NAME"
  echo "SOURCE_DIRECTORY Directory that should be backed up. Please, no trailing slash."
  echo "NAME A string that is used to name the backup in the destination."
  exit 1
}

function single() {
  if grep -qs "$budir " /proc/mounts
  then
    fullname="$budir/$hostname/$name"
    printf "\n"
    printf "Attempting backup of source directory '%s' to '%s'.\n" "$srcdir" "$fullname"
    printf "Number of differential backups to keep: %s\n" "$num"
    printf "Removing oldest backup... "
#    rm -rf "$fullname.$num"
    rsync --archive --delete "$budir/empty/" "$fullname.$num/"		# This is quicker than rm.
    printf "Done.\n"
    for ((i=$num; i>=2; i--)); do
      printf "Renaming '%s' to '%s' ... " "$fullname.$((i-1))" "$fullname.$i"
      mv "$fullname.$((i-1))" "$fullname.$i"
      printf "Done.\n"
    done
    printf "Duplicating last backup ('%s' to '%s')... " "$fullname.0" "$fullname.1"
    [[ -d $fullname.1 ]] && exit 1							# This directory should not exist at that point.
    cp -al "$fullname.0" "$fullname.1"
#    rsync --archive --acls --xattrs --hard-links "$fullname.0/" "$fullname.1/"
    printf "Done.\n"
    now=$(date)
    printf "\n\n\n" >> "$fullname.log"
    printf "STARTING INCREMENTAL BACKUP AT %s\n" "$now" >> "$fullname.log"
    printf "Starting new incremental backy uppy at '%s.0'..." "$fullname"
    if rsync --exclude ".cache" --archive --no-links --delete "$srcdir/" "$fullname.0/" 2>&1 | tee -a "$fullname.log"
    then
      printf " Done.\n"
      printf "Done.\n" >> "$fullname.log"
    else
      printf " Failed.\n"
      printf "Failed.\n" >> "$fullname.log"
    fi
    now=$(date)
    printf "\nIf this line is here the script finished (with or without errors) at %s\n" "$now" >> "$fullname.log"
  else
    printf "'%s' is not mounted. Aborting." "$budir"
    exit 1
  fi
}

function fromlist() {
  while read job; do
    if [ -n "$job" ]; then
      name="${job#* }"
      srcdir="${job% *}"
      single
    fi
  done < "$list"
}

mkdir "$budir/empty"									# Empty directory for a quicker method to delete a large directory.

case $# in
0)
  mount "$budir"
  printf "Reading backup jobs from list. Defaulting to %s.\n" "$list"
  fromlist
  ;;
1)
  mount "$budir"
  list="$1"
  printf "Reading backup jobs from %s." "$list"
  fromlist
  ;;
2)
  mount "$budir"
  single
  ;;
3)
#  I can't decide whether to make the third argument num or budir. I don't need it anyway.
#  num=$3
#  budir=$3
#  mount $budir
#  single
  usage
  ;;
*)
  usage
  ;;
esac

exit 0
Comment via email
Mastodon