BASH - SSH diff


This script outputs 2 diff files from a local directory and a remote directory: one compares the sub-directories one compares the files.

This is useful for comparing a stage environment to a production environment before you push anything to production.
It requires the config file.

script
#!/bin/bash
bold=`tput bold`
off=`tput sgr0`
 
if [ -z "$1" ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]
then
  echo "Usage: " `basename $0` " CONFIG_FILE"
  echo
  echo "--------Config File Variables--------"
  echo "${bold}local_dir_to_diff${off}       Local directory to compare"
  echo "${bold}remote_dir_to_diff${off}      Remote directory to compare"
  echo
  echo "${bold}remote_server${off}           Connect to this server"
  echo "${bold}remote_user${off}             Login in as this user"
  echo
  echo "${bold}output_diff_dir${off}         Output directory for diff results"
  echo "${bold}output_file_diff_file${off}   Name of the output diff file with"
  echo "                        file differences"
  echo "${bold}output_dir_diff_file${off}    Name of the output diff file with"
  echo "                        directory differences"
  echo
  echo "${bold}exclude_dirs${off}            List of directories to exclude"
  echo "-------------------------------------"
 
  exit 0
else
# Read in config file
  . "$1" #there is a dot at the start of this line
fi
 
 
# Local VARs
remote_diff_file_file=/tmp/remote_file.difftmp
remote_diff_dir_file=/tmp/remote_dir.difftmp
local_diff_file_file=/tmp/local_file.difftmp
local_diff_dir_file=/tmp/local_dir.difftmp
 
# Start
 
# Get file information
echo
echo "${bold}Starting${off}"
echo "Your password will be asked for twice"
echo
echo "${bold}Getting file differences${off}"
echo "please enter password for $remote_user@$remote_server"
 
ssh $remote_user@$remote_server "find $remote_dir_to_diff -type f -name '*' -printf '\t%TY-%Tm-%Td\t%TT\t%s\t%p\n' | sort -k4" > $remote_diff_file_file
 
echo "${bold}processing...${off}"
find $local_dir_to_diff -type f -name '*' -printf '\t%TY-%Tm-%Td\t%TT\t%s\t%p\n' | sort -k4 > $local_diff_file_file
 
 
# Get directory information
echo
echo "${bold}Getting directory differences${off}"
echo "please enter password for $remote_user@$remote_server"
 
ssh $remote_user@$remote_server "find $remote_dir_to_diff -type d -name '*' -printf '\t%p\n' | sort" > $remote_diff_dir_file
 
echo "${bold}processing...${off}"
find $local_dir_to_diff -type d -name '*' -printf '\t%p\n' | sort > $local_diff_dir_file
 
 
# Remove excluded dirs...  because i wasn't smart enough to do the processing with 'find'
for j in $remote_diff_file_file \
         $remote_diff_dir_file \
         $local_diff_file_file \
         $local_diff_dir_file
do
        for i in $exclude_dirs
        do
        h="`readlink -f $i`"
                `sed -i -r -e "s#^.*$h.*##" $j`
        done
    `sed -i -e "/^$/d" $j` #remove blank lines
done
 
 
# Creating and editing diffs.  Magic time.
echo
echo "${bold}Creating file diffs${off}"
 
diff -awB --unified=0 --label "$local_dir_to_diff" --label "$remote_user@$remote_server:$remote_dir_to_diff" $local_diff_file_file $remote_diff_file_file | sed -e '/^[^-+].*/d' |sort -k5 > $output_diff_dir/$output_file_diff_file
 
echo "${bold}Creating directory diffs${off}"
 
diff -aw --unified=0 --label "$local_dir_to_diff" --label "$remote_user@$remote_server:$remote_dir_to_diff" $local_diff_dir_file $remote_diff_dir_file | sed -e '/^[^-+].*/d' > $output_diff_dir/$output_dir_diff_file
 
echo
echo "${bold}Done!  Differences are found at:${off}"
echo "  $output_diff_dir"

sshdiff_remote.server.conf
local_dir_to_diff=/home/me/stage
remote_dir_to_diff=/home/shared/production
 
remote_server=remote.server
remote_user=shared
 
output_diff_dir=/home/me/differences
output_file_diff_file="`basename $remote_dir_to_diff`_file_differences_`date +%Y%m%d_%H%M%S`.txt"
output_dir_diff_file="`basename $remote_dir_to_diff`_directory_differences_`date +%Y%m%d_%H%M%S`.txt"
 
exclude_dirs="$local_dir_to_diff/junk
               $local_dir_to_diff/logs
               $remote_dir_to_diff/junk
               $remote_dir_to_diff/logs"

code snippets are licensed under Creative Commons CC-By-SA 3.0 (unless otherwise specified)