Skip to content

Instantly share code, notes, and snippets.

@criztovyl
Last active August 29, 2015 14:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save criztovyl/94a65f4262da4f224181 to your computer and use it in GitHub Desktop.
Save criztovyl/94a65f4262da4f224181 to your computer and use it in GitHub Desktop.
Keeps directories up-to-date
#!/bin/bash
# This is a program for simpler rsync syncing.
# Copyright (C) 2015 Christoph "criztovyl" Schulz
#
# 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 3 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, see <http://www.gnu.org/licenses/>.
###
# ToDo
# - delete missing files/directories (removed files/dirs)
# - configure lock indicators (currently .git and .nosync)
###
# Constants
#
EX_HELP=1
EX_NO_TARGET=2
TRUE=1
ASK_YES_LC="y"
ARG_FAT="fat"
ARG_GO="go"
###
# Init
#
# Args
target=$1
go=$2
fat=$3
[ "${fat,,}" == "$ARG_FAT" ] && fat=$TRUE
[ "${go,,}" == "$ARG_FAT" ] && go=$3 && fat=$TRUE
# Declarations
sim=
src="."
excludeF=".exclude"
oldExcludeF=".exclude.rsync"
# Ignore dirs contain file or directory with this name.
# Usage: name:[type]|name:[type]|...
# name: file/directory name
# type: f for file, d for directory (optimal)
nosync=".nosync:f|.git:d"
###
# Check help and if command line is valid.
#
if [ "$1" = "help" ] || [ "$1" = "--help" ] || [ "$1" = "-h" ] ; then
echo "Args: TARGET [FAT] [GO]"
echo " TARGET: Target dir"
echo " FAT: Synchronizing with/from FAT drive (modifications times encoded differently) (optional)"
echo " GO: use $ARG_NO to disable dry run (as by default) (optional)"
exit $EX_HELP
elif [ -z "$1" ]; then
echo "No Target given!"
exit $EX_NO_TARGET
fi
###
# Check for old exclude file, ask for rename
#
[ -f $oldExcludeF ] &&
{
# Read single yes/no character
read -n 1 -p "Exclude file renamed, is now \""$excludeF"\", do you want to rename? [n/Y] " rename
# Determine answer and renames file on yes (y or Y) or on nothing (newline)
# Also determines if need to add a newline (if entered single character, not newline)
nl="\n"; [ -z "$rename" ] && nl="" || [ "${rename,,}" == "$ASK_YES_LC" ] && mv -i .exclude.rsync $excludeF || echo -ne "$nl"
}
###
# rsync Arguments
#
# Recursiv, time-preserving update with verbose itemized output and progress.
args="-ruti --progress"
# Modification time difference if FAT
[ "$fat" == "$TRUE" ] && args=$args" --modify-window=1"
# Detect action
[ ! $go ] || [ ! "$go" == "$ARG_GO" ] &&
{
args=$args" -n"
sim_msg="Simulation ran, now type \`dirsync-micro $1 $2 $ARG_GO\` to do the synchronisation."
}
###
# Locked dirs
#
# Get lock indicator definitions
IFS="|" read -a locks <<<"$nosync"
# Iterate definitions
for lock in ${locks[@]}; do
# Split name and type
IFS=":" read -a lock <<<"$lock"
# find command
find_command="find $src -iname \"${lock[0]}\""
# If available, set type
[ "${lock[1]}" ] && find_command=$find_command" -type ${lock[1]}"
echo "Looking up ${lock[0]}-locked dirs..."
# Execute command
paths=`eval $find_command`
# iterate over paths
for path in $paths; do
# Replace preceding dot with slash, because in rsync slash is current/base directory
path=${path/#.\//}
# Remove the indicator from the path to get parent directory
path=${path/${lock[0]}/}
# Append as pattern to arguments
args=$args" --exclude=$path**"
done;
done;
###
# Excludes file
#
# If available, set exclude patterns file. Also exclude itself from syncing.
[ -f "$excludeF" ] && args=$args" --exclude=$excludeF --exclude-from=$excludeF"
###
# Sync
#
command="rsync $args $src $target"
echo "Running rsync..."
$command
echo "rsync finished with exit status $?"
# Debug :)
#echo $command
# Echo simulation message
[ "$sim_msg" ] && echo $sim_msg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment