diff/cmp for remote files

December 24, 2009

rdiff, rcmp – diff remote files

rdiff and rcmp extends the diff and cmp utilities to remote files.
Each file or directory argument is either a remote filename of the form [[user@]host1:]file, or a local filename.

Note: the scp program is used to retrieve a remote file. Setting up ssh authentication (~/.ssh/authorized_keys on the remote host ) may be required. Google ‘ssh authorized keys’ for info.
Note2: rdiff can be hardlink’d to rcmp (ie: ln rdiff rcmp). The filename is used to determine functionality.

Example usages:
    $ rdiff -b produser@prodhost:/home/prod/bin/xyz.sh xyz.sh
    $ rcmp produser@prodhost:/home/prod/javalib/xyz.jar $HOME/dev/java/lib/xyz.jar
    $ rcmp ruser@rhost:/usr/local/abc:def /usr/local/abc:def

#! /bin/sh
#  Name: 
#  Synopsis:    rdiff [-b] [[user@]host1:]file1 [[user@]host2:]file2
#               rcmp [[user@]host1:]file1 [[user@]host2:]file2
#  Description: Run diff/cmp on remote files.  
#               Note: This script uses scp or rcp to copy remote files.
#                     (~/.ssh/.authorized_keys, or ~/.rhosts may need to be configured)
#               Note2: Simple pattern matching is used to determine if a file is remote or local 
#                      The filename matches a "user@host:" or "host:" prefix pattern.  To force
#                      a match for a local file, specify the full path with the leading '/'.

getfile() 
{
        if perl -e 'exit !(($ARGV[0] =~ /.*\@.*:\/.*/) || ($ARGV[0] =~ /.*:\/.*/)) &&
                         !($ARGV[0] =~ /\/.*/);' $1; then
                scp "$1" "$2"
                # rcp "$1" "$2"
        else
                ln "$1" "$2";  # This is slight overkill, after all we already
                               # have the file.  But, it simplifies file cleanup...
        fi
}


# Main
case $0 in
  *rdiff) cmd=diff;;
  *rcmp) cmd=cmp;;
esac

while getopts b opt; do
        case $opt in
          b) options="${options} -b";;
        esac
done
shift `expr $OPTIND - 1`

TMPDIR=$HOME/.tmp
tmpfile1=$TMPDIR/r${cmd}1.$$
tmpfile2=$TMPDIR/r${cmd}2.$$
trap "rm -f $tmpfile1 $tmpfile2" 0 15

if getfile "$1" "$tmpfile1" && getfile "$2" "$tmpfile2"; then
        eval $cmd $options $tmpfile1 $tmpfile2
fi