Skip to content

Instantly share code, notes, and snippets.

@b0o
Created April 6, 2019 07:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save b0o/b53d840e5ce07354b5b0fb0a0c818f04 to your computer and use it in GitHub Desktop.
Save b0o/b53d840e5ce07354b5b0fb0a0c818f04 to your computer and use it in GitHub Desktop.
#!/bin/bash
set -euo pipefail
initfile_name="rclonesync-init.txt"
watch=0
watch_interval=-1
watch_timeout=30
cmd=""
remote=""
syncpoint=""
firstsync=""
user="$(whoami)"
group=""
umask=""
apply_chown=0
apply_chmod=0
timeout=0
sync() {
[[ -z "$syncpoint" ]] && {
echo "$0: fatal: no syncpoint specified" >&2
return 1
}
[[ -z "$remote" ]] && {
echo "$0: fatal: no remote specified" >&2
return 1
}
[[ ! -e "$syncpoint" ]] && mkdir -p "$syncpoint"
[[ ! -d "$syncpoint" ]] && {
echo "$0: fatal: not a directory: $syncpoint" >&2
return 1
}
echo "$0: sync '$remote' to '$syncpoint'" >&2
rccmd="rclonesync -v"
rccmd+=" --rclone rclonesync-rclone"
rccmd+=" $firstsync"
rccmd+=" $remote $syncpoint"
[[ -n "$firstsync" ]] && {
firstsync=""
find "$syncpoint" -mindepth 1 -name '*' | [[ $(wc -l) -eq 0 ]] && {
echo "touch $syncpoint/$initfile_name" >&2
echo "This file was created as a placeholder when initializing rclonesync. You may delete it safely." >> "$syncpoint/$initfile_name"
}
}
echo "running $rccmd" >&2
eval "$rccmd"
[[ -e "$syncpoint/$initfile_name" ]] && {
find "$syncpoint" -mindepth 1 -name '*' | [[ $(wc -l) -gt 1 ]] && {
rm --preserve-root -v "$syncpoint/$initfile_name"
}
}
[[ $apply_chown -eq 1 ]] && {
local co="chown --preserve-root -chvR $user:$group $syncpoint"
echo "applying ownership: $co"
eval "$co"
}
[[ $apply_chmod -eq 1 ]] && {
local cm="chmod --preserve-root -cvR $umask $syncpoint"
echo "applying umask: $cm"
eval "$cm"
}
return 0
}
main() {
local OPTIND OPTARG
while getopts "1wr:s:t:i:u:g:M:" opt; do
case $opt in
1)
firstsync="--first-sync"
;;
w)
watch=1
;;
r)
remote="$OPTARG"
;;
s)
syncpoint="$OPTARG"
;;
t)
watch_timeout="$OPTARG"
;;
i)
watch_interval="$OPTARG"
;;
u)
apply_chown=1
user="$OPTARG"
;;
g)
apply_chown=1
group="$OPTARG"
;;
M)
apply_chmod=1
umask="--umask $OPTARG"
;;
\?)
echo "$0: fatal: unknown option $OPTARG" >&2
return 1
;;
esac
done
shift $((OPTIND - 1))
cmd="${1:-sync}"
group="${group:-$(id -gn "$user")}"
[[ $watch -eq 1 ]] && {
watch
return $?
}
run_cmd
}
watch_handle_event() {
read -r evt
echo "handle event: $evt" >&2
t=$((timeout - $(date +%s)))
[[ $timeout -ne 0 && $t -gt 0 ]] && {
echo "timed out for $t seconds - sleeping..." >&2
sleep $t
}
run_cmd
timeout=$(($(date +%s) + watch_timeout))
}
watch() {
watch_handle_event <<< "INIT"
echo "watching $syncpoint..." >&2
local e=""
while true; do
e="$(inotifywait -qrt "$watch_interval" -e modify,attrib,move,create,delete "$syncpoint")" || {
e="INTERVAL"
}
watch_handle_event <<< "$e"
done
}
run_cmd() {
case $cmd in
sync)
sync
;;
\?)
echo "$0: fatal: unknown command '$cmd'" >&2
return 1
;;
esac
}
main "$@"
# vim: set ts=2 sw=2 tw=80 noet :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment