Tag Archives: external

Bash script for complete system backup on external hard drive using tar

Some time ago I posted a script to backup Linux system to external drive using rsync. As the task this time was to create an archive of the whole system and the old backup files to be removed the script had to be changed a bit. Here is the version of it with the use of tar command. As before your external drive’s mount point has to be defined in fstab file.

And this is the script, it does not need much explanation:

 

#!/bin/bash

# Script to create full system archived backup to external USB drive.

# Specify the mount point, backup path and other stuff here (DO NOT end mount_point with a forward-slash).

mount_point=’/mnt/WD’
current_year=`date +%Y`
current_day=`date +’%Y-%m-%d_%H:%M:%S’`
backup_path=${mount_point}’/backup/’${current_year}
files_to_keep=2

echo “#####”
echo “”

# Check whether target volume is mounted, and mount it if not.

if ! mountpoint -q ${mount_point}/; then
   echo “Mounting the external USB drive.”
   echo “Mountpoint is ${mount_point}”
      if ! mount ${mount_point}; then
         echo “An error code was returned by mount command!”
         exit 5
      else echo “Mounted successfully.”
      fi
else echo “${mount_point} is already mounted.”;
fi

# Target volume **must** be mounted by this point.

if ! mountpoint -q ${mount_point}/; then
   echo “Mounting failed! Cannot run backup without backup volume!”
   exit 1
fi

echo “Preparing the archive using tar.”

mkdir –parents ${backup_path}/

tar czf ${backup_path}/${current_day}_backup.tar.gz –exclude=${backup_path}/${current_day}_backup.tar.gz –exclude=/dev/* –exclude=/mnt/* –exclude=/proc/* –exclude=/sys/* –exclude=/run/* –exclude=/media/* –exclude=/tmp/* –exclude=/lost+found /

# Delete old backup files

cd ${backup_path}/

rm -f `ls -t *_backup.tar.gz | awk “NR>$files_to_keep”`

cd /

# Dismounting target volume

if ! umount ${mount_point}; then
   echo “An error code was returned by command!”
   exit 5
else
echo “Dismounted successfully.”;
fi

 

And you are good to go! 🙂


Linux – Bash script for complete system backup on external hard drive using rsync

Now before you read this article I strongly advise you to read those once first if you think you are not too familiar with this subject.  The first one is located HERE and is a very good explanation on how to use rsync for full OS backup. The second one is a detailed explanation on backing up data on to external USB drive by Bobulous, which you can find HERE. The script in this article is a modified version of the original script created by Bobulous as I needed to achieve few other things as well.

It is kind of important to get your fstab file organized first. Do not forget to modify it so your external hard drive gets the same mount point every time it is mounted. For this you will have to find out what your drive UUID is. As an example, the line in my fstab file look like:

 

UUID=ff0ba5cf-dc79-4b96-a86b-a64f26154232 /mnt/sync ext4 user,noauto,noatime     0     0

 

As I wanted the drive to be used only for the purpose of system backup I did not want it working all the time, so I wanted not just to unmount, but eject it as well and switch it off after use. This is where udisks utility comes handy, if it is not installed on your system – you will have to install it so the script works as it should. But udisks does not use the UUID to handle the drive, so the correct device file mapping has to be found.

The first thing is to extract the UUID, this is done in variable declaration:

 

uuid=`cat /etc/fstab | grep ${mount_point} | cut -c 6-41`

 

Before using the script make sure the result of the commands is the UUID of your drive, take care of cut command and adjust it if the output is not exactly what you are expecting. Or instead of cut you can use sed command, which might be a bit more universal:

 

uuid=`cat /etc/fstab | grep ${mount_point} | sed -r ‘s_.*=(.*) ${mount_point}.*_\1_’`

 

though I haven’t tried it myself.

After the disk is successfully mounted the declaration of HDID takes care of finding the correct device file:

 

HDID=`ls -l /dev/disk/by-uuid/${uuid} | sed -r ‘ s_^.* -> ../../(…).$_\1_’`

 

If you are like me and find sed command often confusing – there is a great tutorial about it by Bruce Barnett.

The actual backup work is done by rsync command, but you may want to adjust it depending on your Linux distribution, I run it on Debian 7 and it works fine for me.

And this is the script itself, you can modify it to suit your needs:

 

#!/bin/bash

# Script to backup full ystem to the external USB drive.

# Specify the mount point here (DO NOT end mount_point with a forward-slash).

mount_point=’/mnt/sync’

 

# Set the backup path here (DO NOT end mount_point with a forward-slash).

backup_path=${mount_point}

 

#Find UUID by mount point

uuid=`cat /etc/fstab | grep ${mount_point} | cut -c 6-41`

 

echo “#####”

echo “”

# Check whether target volume is mounted, and mount it if not.

if ! mountpoint -q ${mount_point}/; then

                echo “Mounting the external USB drive.”

                echo “Mountpoint is ${mount_point}”

                if ! mount ${mount_point}; then

                                echo “An error code was returned by mount command!”

                                exit 5

                else echo “Mounted successfully.”

                     HDID=`ls -l /dev/disk/by-uuid/${uuid} | sed -r ‘ s_^.* -> ../../(…).$_\1_’`

                     echo “${HDID} is the backup drive ID”;

                fi

else echo “${mount_point} is already mounted.”;

fi

# Target volume **must** be mounted by this point. If not, die screaming.

if ! mountpoint -q ${mount_point}/; then

                echo “Mounting failed! Cannot run backup without backup volume!”

                exit 1

fi

 

echo “Preparing to transfer differences using rsync.”

 

echo “Backup storage directory path is ${backup_path}”

 

echo “Starting backup of / . . . “

 

rsync -aAXHhv /* ${backup_path}/ –progress –delete –exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}

 

# Ask user whether target volume should be unmounted.

echo -n “Do you want to unmount ${mount_point} and eject the drive (no)”

read -p “: ” unmount_answer

unmount_answer=${unmount_answer,,}  # make lowercase

if [ “$unmount_answer” == “y” ] || [ “$unmount_answer” == “yes” ]; then

                if ! umount ${mount_point}; then

                                echo “An error code was returned by command!”

                                exit 5

                else echo “Dismounted successfully.”

                     udisks –detach /dev/${HDID}

                     echo “Disk ejected.”;

                fi

else echo “Volume remains mounted.”;

fi

 

echo “”

echo “####”