Heading to the Beach

0

Synchronizing my laptop with rsync

Tomorrow, Saturday as I write this, we’ll be heading to Atlantic Beach, our current favorite. By the time you read it, we’ll be there enjoying the amazing views including the one in the picture above. We do this every year. We also travel to visit family, and I travel for the occasional conference.

To make my computing life as seamless as possible, I take my System76 Serval WS laptop with us — or me as the case may be. I always sync my home directory from my primary workstation to my laptop, named Voyager3 or vgr3 for short. As that name implies, I have two other System76 laptops.

My requirements

A few years ago, I would sync my laptop by hand, just picking out a few directories to copy over from my workstation. That became very tedious and I decided to write a script using the rsync program. I’d already started using rsync for my backups and knew it could do what I needed. My article, Using rsync for Backup, describes how rsync works.

My synchronization program must meet the following requirements:

  1. Be easy to use.
  2. Have a command line user interface that is easily understandable.
  3. Use Bash as its programming language.
  4. Have an integrated help function.
  5. Minimize network traffic.
  6. Be fast.
  7. Run as a non-root user — namely me.

The program

I wrote this Bash program named syncVgr.sh to meet those requirements. It does exactly what I need and does it well and fast. This program, despite the comments, help, and GPL, that I’ve included, is rather small at only 250 lines, so I’ve copied it here in its entirety.

#!/bin/bash
################################################################################
#                               syncVgr.sh                                     #
#                                                                              #
# This simple bash program syncs my home directory on host david to the one    #
# on vgr so that when I travel I have the latest files available.              #
#                                                                              #
#                                                                              #
#                               Changelog                                      #
#   Date      Who      Description                                             #
#-----------  -------- --------------------------------------------------------#
# 2022/10/15  dboth    Initial code for concept and initial testing.           #
# 2022/11/15  dboth    Fix initial problems so that excluding cache now works. #
#                                                                              #
#                                                                              #
#                                                                              #
#                                                                              #
################################################################################
################################################################################
################################################################################
#                                                                              #
#  Copyright (C) David Both 2022                                               #
#  LinuxGeek46@both.org                                                        #
#                                                                              #
#  This program is free software; you can redistribute it and/or modify        #
#  it under the terms of the GNU General Public License as published by        #
#  the Free Software Foundation; either version 2 of the License, or           #
#  (at your option) any later version.                                         #
#                                                                              #
#  This program is distributed in the hope that it will be useful,             #
#  but WITHOUT ANY WARRANTY; without even the implied warranty of              #
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
#  GNU General Public License for more details.                                #
#                                                                              #
#  You should have received a copy of the GNU General Public License           #
#  along with this program; if not, write to the Free Software                 #
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   #
#                                                                              #
################################################################################
################################################################################


################################################################################
# Help                                                                         #
################################################################################
help()
{
   # Display help
   echo
   echo "################################################################################"
   echo "                                 syncVgr.sh"
   echo
   echo "Performs backups of the /home/dboth directory on the host $ThisHost to the "
   echo "laptop $RemoteHostName using rsync. Use this program to sync voyager (vgr) "
   echo "prior to a trip."
   echo
   echo "Run this program as the user dboth. The password will be required."
   echo
   echo "Syntax: syncVgr.sh -[g|h|s|V]v "
   echo "options:"
   echo "g     Print the GPL license statement."
   echo "h     Display this help screen."
   echo "s     Perform the sync operation."
   echo "t     Test mode. Performs all functions except the actual sync. "
   echo "V     Print version number and exit."
   echo "v     Verbose mode."
   echo
   echo "################################################################################"
   echo
}
################################################################################
# Print the GPL license header                                                 #
################################################################################
gpl()
{
   echo
   echo "################################################################################"
   echo "#  Copyright (C) David Both 2022                                               #"
   echo "#  LinuxGeek46@both.org                                                        #"
   echo "#  http://www.both.org                                                         #"
   echo "#                                                                              #"
   echo "#  This program is free software; you can redistribute it and/or modify        #"
   echo "#  it under the terms of the GNU General Public License as published by        #"
   echo "#  the Free Software Foundation; either version 3 of the License, or           #"
   echo "#  (at your option) any later version.                                         #"
   echo "#                                                                              #"
   echo "#  This program is distributed in the hope that it will be useful,             #"
   echo "#  but WITHOUT ANY WARRANTY; without even the implied warranty of              #"
   echo "#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #"
   echo "#  GNU General Public License for more details.                                #"
   echo "#                                                                              #"
   echo "#  You should have received a copy of the GNU General Public License along     #"
   echo "#  with this program; if not, If not, see <https://www.gnu.org/licenses/>.     #"
   echo "################################################################################"
   echo
}
  
################################################################################
# Quit nicely with messages as appropriate                                     #
################################################################################
Quit()
{
   if [ $verbose = 1 ]
      then
      if [ $error = 0 ]
         then
         echo "Program terminated normally"
      else
         echo "Program terminated with error $error";
      fi
   fi
   exit
}

################################################################################
# Gets simple (Y)es (N)o (Q)uit response from user. Loops until                #
# one of those responses is detected.                                          #
################################################################################
ynq()
{
   # loop until we get a good answer and break out
   while [ $OK = 0 ]
   do
      # Print the message
      echo -n "$message (ynq) "
      # Now get some input
      read input
      # Test the input
      if [ $input = "yes" ] || [ $input = "y" ]
         then
         response="y"
         OK=1
      elif [ $input = "no" ] || [ $input = "n" ]
         then
         response="n"
         OK=1
      elif [ $input = "help" ] || [ $input = "h" ]
         then
         help
      elif [ $input = "q" ] || [ $input = "quit" ]
         then
         Quit
      else
         # Invalid input
         echo "INPUT ERROR: Must be y or n or q in lowercase. Please try again."
      fi
   done
}

################################################################################
################################################################################
# Main program                                                                 #
################################################################################
################################################################################
################################################################################
# Initialization                                                               #
################################################################################
# Set initial variables
badoption=0
SourcePath="/home/dboth/"
TargetPath="/home/dboth/"
# TargetPath="/Test/home/dboth/"
error=0
gpl=0
RemoteHostName="vgr3"
nooption=1
OK=0
SyncIt=0
TestMode=0
ThisHost=`hostname | awk -F. '{print $1}'`
TimeStamp="TimeStamp"
verbose=0
version=2.4.0

################################################################################
# Process the input options                                                    #
################################################################################
# Get the options
while getopts ":ghstvV" option; do
   case $option in
      g) # display GPL license text
         nooption=0
         gpl
         Quit
         ;;
      h) # display help
         nooption=0
         help
         Quit
         ;;
      s) # Perform the sync
         nooption=0
         SyncIt=1
         ;;
      t) # Test mode
         nooption=0
         TestMode=1
         ;;
      v) # Set verbose mode
         nooption=0
         verbose=1
         ;;
      V) # Print Version number
         echo "rsbu Version $version"
         Quit
         ;;
     \?) # incorrect option
         nooption=0
         badoption=1
         ;;
   esac
done

if [ $nooption = 1 ]
   then
   echo "ERROR: No option entered. You must enter at least one valid option."
   help
   verbose=1
   error="ID10T"
   Quit
fi

if [ $badoption = 1 ]
then
   echo "ERROR: Invalid option"
   help
   verbose=1
   error="ID10T"
   Quit
fi


################################################################################
# Do the sync                                                                  #
################################################################################

if [ $SyncIt = 1 ]
   then
   # This is the normal command that excludes a large number of cache and hidden files.
   # rsync -aH --exclude="*cache" --exclude=".*" -e ssh $SourcePath $RemoteHostName:$TargetPath
   # This is the copy everything command.
   rsync -aH --progress -e ssh $SourcePath $RemoteHostName:$TargetPath
fi
################################################################################

Quit

You can copy this program from here, but I hope to get it added to my downloads page soon. It’s fairly self-explanatory and the comments, plus the article, Using rsync for Backup, describing how rsync works, should help you understand the code.

The best way to use this program is to set up a public/private keypair (PPKP) on your source computer, my main workstation for me, and copy the public key to the target laptop. That is a more secure method of granting yourself access to the remote host than using a password.

It’s not done yet

I’ve used this program for a few years, but I think there are a couple changes I could make to it. See if you can find them. Send us an email to open@both.org to let us know what you’ve found that can be improved.

Enjoy!

Leave a Reply