#!/bin/bash set -e SSHARGS="-t -o ControlPath=~/.ssh/master-$$ -o ControlMaster=auto -o ControlPersist=600" function error_handler { echo "Error in $*" if [ -n "$redirect" ] then cat /tmp/${USER}_unison.log fi } function sync_dir { # looking for .fsignore file if [ -f $dir/.fsignore ] then ignore_txt=".. ignoring" ignore="" while read line do ignore_txt="$ignore_txt: $line" ignore="$ignore -ignore \"Name $line\"" done < $dir/.fsignore echo $ignore_txt fi #syncing data eval "unison -sshargs \"$SSHARGS\" $fat -batch $ignore $dir ssh://$user/unison_dirs/$dir $redirect" || error_handler "sync_dir/unison" $* if [ -n "$redirect" ] then grep "\-\-\-" /tmp/${USER}_unison.log || true grep "\[CONFLICT\]" /tmp/${USER}_unison.log || true grep "error" /tmp/${USER}_unison.log || true fi } function force { direction=$1 dir=$2 user=$3 # looking for .fsignore file if [ -f $dir/.fsignore ] then ignore="--exclude-from=$dir/.fsignore" fi if [ "$direction" = "up" ] then rsync -av --delete $ignore $dir/ ${user}:unison_dirs/$dir/ || error_handler "force/rsync" $* sync_dir $* elif [ "$direction" = "down" ] then if eval "rsync -av --delete $ignore ${user}:unison_dirs/$dir/ $dir/ $redirect" then sync_dir $* else error_handler "force/rsync" $* fi else echo "invalid direction parameter" >&2 exit 2 fi } function syncDir { # $1: base dir # $2: dir # $3/4: flags (optional): # -r: retry, if base dir is missing # -f: dir is a FAT file system # -i IGNORE: add ignore pattern. May be present more than once # -u [USER@]HOST: ssh-Login basedir=$1 dir=$2 retry= fat="" user="wagnertech.de" # for downward compatibility ignore="" force= redirect="1>/tmp/${USER}_unison.log 2>&1" while : do case $3 in -r) retry=true shift 1 ;; -p) force=up shift 1 ;; -d) force=down shift 1 ;; -f) fat="-fat" shift ;; -i) #ignore pattern -> depricated echo "Use of -i option in config file is deprecated." echo "Use .fsignore file instead (see man page)" shift 2 ;; -u) user=$4 shift 2 ;; -v) redirect="" shift 1 ;; --) # End of all options shift break ;; -*) echo "Unknown option: $3" >&2 exit 1 ;; *) # no more options. Stop while loop break ;; esac done # looking for base dir if [ -d $basedir ] then pushd $basedir >/dev/null || exit 1 # looking for sync dir if [ ! -d $dir ] then echo "$dir not existing." >&2 exit 1 fi echo "syncing $dir ..." # sync .fsignore in advance localign=$(test -f $dir/.fsignore; echo $?) remoteign=$(ssh $SSHARGS -n $user "ls unison_dirs/$dir/.fsignore" 1>/dev/null 2>&1; echo $?) || error_handler "syncDir/ssh1" $* if [ $localign -eq 0 -a $remoteign -eq 0 ] then if ! eval "unison -sshargs \"$SSHARGS\" $fat -batch $dir/.fsignore ssh://$user/unison_dirs/$dir/.fsignore $redirect" then echo "syncing .fsignore failed" fi elif [ $localign -ne 0 -a $remoteign -eq 0 ] then scp $user:unison_dirs/$dir/.fsignore $dir/ || error_handler "syncDir/scp" $* fi if [ -n "$force" ] then force $force $dir $user return fi # check existence of remote directory if ! eval ssh $SSHARGS -n $user "ls -d unison_dirs/$dir" $redirect then echo "ssh problem or remote directory not existing." echo "Try a ssh login to $user, then do a 'mFileSync -p'." error_handler "syncDir/ssh2" $* else sync_dir $* fi echo "done." popd >/dev/null else if [ "$retry" != "true" ] then echo "$basedir not existing." exit 1 fi echo "Waiting for base dir $basedir." fi } usage="mFileSync " if [ $# -lt 1 ] then echo $usage exit 1 fi if [ -f $1 ] then # process config dir while true do # read config file while read line do if [ ${line:0:1} != "#" ] then base=${line%%,*} tmp=${line%,*} dir=${tmp#*,} flags=${line##*,} syncDir $base $dir $flags fi done < $1 sleep 60 done else # process single directory syncDir . $* fi