Thursday, February 26, 2009

synchronize work spaces on different machines

While working on a set of files on different machines, it's a common problem to keep things in sync. A real solution is to use a revision control system (with git being my current favorite). However, a quick fix is to use rsync. Following script tries to figure out which copy of the work space is newer and invokes rsync accordingly.
#!/bin/bash
if (( $# != 3 )); then
        echo "Usage: `basename $0` <local file> <remote host> <remote file>"
        exit 1;
fi
LOCAL_FILE="$1"
REMOTE_HOST="$2"
REMOTE_FILE="$3"

# make sure directories end with '/'
if [ -d "${LOCAL_FILE}" ]; then
        LOCAL_FILE=${LOCAL_FILE%/}/
        REMOTE_FILE=${REMOTE_FILE%/}/
        echo "sync directory: '`basename ${LOCAL_FILE}`' with ${REMOTE_HOST}"
else
        echo "sync file: '`basename ${LOCAL_FILE}`' with ${REMOTE_HOST}"
fi

# find out the last modification time in the entire directory
TM_LOCAL=`if [ -e "${LOCAL_FILE}" ]; then find $LOCAL_FILE -printf "%Ts %P\n"|sort|tail -n1; else echo 0; fi`
TM_REMOTE=`ssh ${REMOTE_HOST} "if [ -e \"${REMOTE_FILE}\" ]; then find $REMOTE_FILE -printf \"%Ts %P\n\"|sort|tail -n1; else echo 0; fi" < /dev/null`

echo Local Newest: $TM_LOCAL
echo Remote Newest: $TM_REMOTE
if [[ $TM_LOCAL < $TM_REMOTE ]]; then
        echo -n "remote => local"
        rsync -auz -e ssh --delete ${REMOTE_HOST}:"\"${REMOTE_FILE}\"" "${LOCAL_FILE}"
        echo ",  Done!"
elif [[ $TM_LOCAL > $TM_REMOTE ]]; then
        echo -n "local => remote"
        rsync -auz -e ssh --delete "${LOCAL_FILE}" ${REMOTE_HOST}:"\"${REMOTE_FILE}\""
        echo ",  Done!"
else
        echo "Nothing to do!"
fi