My bash script mounts two VeraCrypt volumes, rsyncs their contents, and dismounts them. The script takes two parameters, the path for both the source and backup veracrypt volumes. I wrote this script so rsync wouldn't have to copy an entire volume if there was a single change in it.
This is my second time with bash scripting so please let me know what I could do better.
Thanks
#!/bin/bash
# Requirements:
# - Must have both veracrypt and rsync installed
# - Must be ran on Unix based systems
# - Both volumes must have the same password
function prepare_volumes_for_exit() {
# dismount volumes
veracrypt -d
echo "Volumes dismounted"
# delete mount points
sudo rm -r "$source_mount_point"
sudo rm -r "$backup_mount_point"
echo "Mount points purged"
}
# removes double or single quotes from strings of they exist
function format_string() {
if [ "${1:0:1}" == "'" ] && [ "${1: -1}" == "'" ]; then
echo "${1:1:-1}"
elif [ "${1:0:1}" == '"' ] && [ "${1: -1}" == '"' ]; then
echo "${1:1:-1}"
else
echo "$1"
fi
}
# make sure all volumes are removed before starting
veracrypt -d
# check that 2 params are passed
if ! [ $# -eq 2 ]; then
echo "Error: 2 parameters are required [source_volume_path] [backup_volume_path]"
exit 1
fi
echo "Enter the password for the veracrypt volume: "
read -s veracrypt_password
# path to veracrypt volumes
source_volume_path="$(format_string "$1")"
backup_volume_path="$(format_string "$2")"
# generate random mount point
source_mount_point="$(format_string "/mnt/$(uuidgen)")"
backup_mount_point="$(format_string "/mnt/$(uuidgen)")"
# flag to determine if drives are mounted
source_volume_mounted=0
backup_volume_mounted=0
# create mount points
sudo mkdir -p "$source_mount_point"
sudo mkdir -p "$backup_mount_point"
echo "Beginning to mount volumes"
sudo veracrypt -t --mount "$source_volume_path" "$source_mount_point" -p "$veracrypt_password" --non-interactive
# checks that the source volume mounted
while read -r drive_number volume_location vc_mapper mount_location; do
formatted_volume_location="$(format_string "$volume_location")"
formatted_mount_location="$(format_string "$mount_location")"
if [ "$formatted_volume_location" == "$source_volume_path" ] && [ "$formatted_mount_location" == "$source_mount_point" ]; then
echo "Source volume mounted"
source_volume_mounted=1
else
echo "Error: source volume not mounted"
prepare_volumes_for_exit
exit 1
fi
done <<< $(veracrypt -t -l)
sudo veracrypt -t --mount "$backup_volume_path" "$backup_mount_point" -p "$veracrypt_password" --non-interactive
# checks both the source and backup volumes are mounted
# http://mywiki.wooledge.org/BashFAQ/001#source
while read -r drive_number volume_location vc_mapper mount_location; do
formatted_volume_location="$(format_string "$volume_location")"
formatted_mount_location="$(format_string "$mount_location")"
if [ "$formatted_volume_location" == "$source_volume_path" ] && [ "$formatted_mount_location" == "$source_mount_point" ]; then
source_volume_mounted=1
elif [ "$formatted_volume_location" == "$backup_volume_path" ] && [ "$formatted_mount_location" == "$backup_mount_point" ]; then
echo "Backup volume mounted"
backup_volume_mounted=1
else
echo "Error: source or backup volume not mounted"
prepare_volumes_for_exit
exit 1
fi
done <<< $(veracrypt -t -l)
if [ "$source_volume_mounted" -eq 1 ] && [ "$backup_volume_mounted" -eq 1 ]
then
echo "Volumes mounted, beginning rsync"
# sudo rsync -hrtq --exclude-from='/media/miller/Primary/exclude.txt' --delete $source_mount_point/ $backup_mount_point
echo "rsync complete"
else
echo 'Error: Drives were not mounted successfully, skipping rsync'
fi
prepare_volumes_for_exit
echo "Complete"
exit 0
```