Keeping a local and cloud file in sync

At home I track all my account transactions in a spreadsheet. When I went on vacation, I had to keep all the receipts to make sure they were entered into the spreadsheet when I returned home. That got me wondering if there’s a way to have access to the file while I am away from home. I started to think about the requirements and how I would update the file while I was away and make sure it synched up with the file at home.

I could have just kept the file on my Box.com account and accessed it from there. But that would pose challenges with locks placed on the file that may not be cleared. So I decided to have two copies of the file; one is stored on my NAS at home and the other is on Box.com. To make sure these files are kept in synch, I created a bash script that is run every 15 minutes by cron. This will check the files to see if there have been any changes, and if so it determines which one is older and overwrites the older one with the newer one. Also I have it send me an email when one of the files are overwritten.

You can view the complete bash script here or download the text file.

#!/bin/bash

# Create blank email
rm /tmp/bank.mail
touch /tmp/bank.mail
echo 'To: your-email@somebogusdomain.com' >> /tmp/bank.mail
echo 'From: server@mytestbox.org' >> /tmp/bank.mail
# Set date variables
fileDate=$(date +%m-%d-%Y-%HH-%MM-%SS)
folderDate=$(date +%m-%d-%Y)
# This section resets and checks to ensure the cloud and local storage is mounted
# /mnt/Warehouse13 is the mount point for my NAS
umount /mnt/Warehouse13
let mountPointA=0
while [ $mountPointA -lt 1 ]; do
if mountpoint -q /mnt/Warehouse13;
then
 # This checks to make sure the file exists
        if [ ! -f /mnt/Warehouse13/Accounts/2014/Household_Accounts_2014.xls ]; then
                echo 'Subject: Checkbook Update Failed - Local File Missing' >> /tmp/bank.mail
                echo '' >> /tmp/bank.mail
                echo '' >> /tmp/bank.mail
                echo 'The local file is missing - '$fileDate >> /tmp/bank.mail
# This next line is what sends the email
                cat /tmp/bank.mail | msmtp -a default your-email@somebogusdomain.com
                exit 0
        else
 # This sets mountPoint to 1 to exit this if then
                let mountPointA=1
        fi
else
 # This checks the mount point and if it has retried more than 100 times, aborts and sends email
        if [ $mountPointA = -100 ]; then
                echo 'Subject: Checkbook Update Failed - Unable to mount local drive' >> /tmp/bank.mail
                echo '' >> /tmp/bank.mail
                echo '' >> /tmp/bank.mail
                echo 'Unable to mount the local drive - '$fileDate >> /tmp/bank.mail
                cat /tmp/bank.mail | msmtp -a default your-email@somebogusdomain.com
                exit 0
        else
 # This attempts the remount and decreases the count by 1
                mount /mnt/Warehouse13
                let mountPointA=mountPointA-1
        fi
fi
done;
rm /var/run/mount.davfs/mnt-box.pid
umount /mnt/box
let mountPointB=0
while [ $mountPointB -lt 1 ]; do
if mountpoint -q /mnt/box;
then
        if [ ! -f /mnt/box/Accounts/2014/Household_Accounts_2014.xls ];
        then
  echo 'Subject: Checkbook Update Failed - Online File Missing' >> /tmp/bank.mail
         echo '' >> /tmp/bank.mail
         echo '' >> /tmp/bank.mail
         echo 'The online file is missing - '$fileDate >> /tmp/bank.mail
         cat /tmp/bank.mail | msmtp -a default your-email@somebogusdomain.com
  exit 0
        else
                let mountPointB=1
        fi
else
        if [ $mountPointB = -100 ]; then
         echo 'Subject: Checkbook Update Failed - Unable to mount Box.com' >> /tmp/bank.mail
         echo '' >> /tmp/bank.mail
         echo '' >> /tmp/bank.mail
         echo 'Unable to mount Box.com' >> /tmp/bank.mail
  cat /tmp/bank.mail | msmtp -a default your-email@somebogusdomain.com
  command || exit
        else
                mount /mnt/box
                let mountPointB=mountPointB-1
        fi
fi
done;
# Define online and offline files
boxFileCheck=/mnt/box/Accounts/2014/Household_Accounts_2014.xls
lanFileCheck=/mnt/Warehouse13/Accounts/2014/Household_Accounts_2014.xls
# Grab filesize
boxFileSize=$(stat -c%s "$boxFileCheck")
lanFileSize=$(stat -c%s "$lanFileCheck")
# Define minimum file size - 600000 bytes is just smaller than my average spreadsheet size
minSize=300000
# This section checks if the file size is larger than minSize. Previous versions of the script would sometimes create 0 byte size files and then copy over the other file with the 0 byte size file
# This was added after internet connectivity issues that would result in an incomplete file transfer.
if [ "$boxFileSize" -lt "$minSize" ]; then
        echo 'Subject: Checkbook Update Failed - The online file is corrupted' >> /tmp/bank.mail
        echo '' >> /tmp/bank.mail
        echo '' >> /tmp/bank.mail
        echo 'The online file is corrupted - Aborting - '$fileDate >> /tmp/bank.mail
        cat /tmp/bank.mail | msmtp -a default your-email@somebogusdomain.com
 exit 0
fi
if [ "$lanFileSize" -lt "$minSize" ]; then
        echo 'Subject: Checkbook Update Failed - The local file is corrupted' >> /tmp/bank.mail
        echo '' >> /tmp/bank.mail
        echo '' >> /tmp/bank.mail
        echo 'The local file is corrupted - Aborting - '$fileDate >> /tmp/bank.mail
        cat /tmp/bank.mail | msmtp -a default your-email@somebogusdomain.com
        exit 0
fi
# Creates MD5 checksum of offline and online files
boxFile2014=$(md5sum '/mnt/box/Accounts/2014/Household_Accounts_2014.xls' | cut -b-32)
localFile2014=$(md5sum '/mnt/Warehouse13/Accounts/2014/Household_Accounts_2014.xls' | cut -b-32)
# This if then checks if the files are the same using the MD5, if not it compares the date and overwrites the older with the new while creating a backup copy
if [ "$boxFile2014" = "$localFile2014" ]; then
 # If the files are the same, based on MD5, exit
 exit 0
elif [ '/mnt/Warehouse13/Accounts/2014/Household_Accounts_2014.xls' -ot '/mnt/box/Accounts/2014/Household_Accounts_2014.xls' ]; then
 # If the offline file is older than the online file, copy the online file offline
 mv '/mnt/Warehouse13/Accounts/2014/Household_Accounts_2014.xls' '/mnt/Warehouse13/Accounts/2014/backups/Household_Accounts_2014_'$fileDate'.bak'
 cp '/mnt/box/Accounts/2014/Household_Accounts_2014.xls' '/mnt/Warehouse13/Accounts/2014/Household_Accounts_2014.xls'
 echo 'Subject: Checkbook Updated - Online > Local' >> /tmp/bank.mail
 echo '' >> /tmp/bank.mail
 echo '' >> /tmp/bank.mail
 echo 'The local checkbook has been update. - '$fileDate >> /tmp/bank.mail
        cat /tmp/bank.mail | msmtp -a default your-email@somebogusdomain.com
 exit 0
elif [ '/mnt/box/Accounts/2014/Household_Accounts_2014.xls' -ot '/mnt/Warehouse13/Accounts/2014/Household_Accounts_2014.xls' ]; then
 # If the online file is older than the offline file, copy the offline file online
 mv '/mnt/box/Accounts/2014/Household_Accounts_2014.xls' '/mnt/box/Accounts/2014/backups/Household_Accounts_2014_'$fileDate'.bak'
 cp '/mnt/Warehouse13/Accounts/2014/Household_Accounts_2014.xls' '/mnt/box/Accounts/2014/Household_Accounts_2014.xls'
 echo 'Subject: Checkbook Updated - Local > Online' >> /tmp/bank.mail
 echo '' >> /tmp/bank.mail
 echo '' >> /tmp/bank.mail
 echo 'The online checkbook has been updated. - '$fileDate >> /tmp/bank.mail
 cat /tmp/bank.mail | msmtp -a default your-email@somebogusdomain.com
 exit 0
else
 exit 0
fi

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>