Last active
August 29, 2015 14:20
-
-
Save criztovyl/94a65f4262da4f224181 to your computer and use it in GitHub Desktop.
Keeps directories up-to-date
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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