Skip to content

Instantly share code, notes, and snippets.

@mujz
Created February 1, 2017 09:00
Show Gist options
  • Save mujz/38c52123104b2f26f7a179dd1e3ce194 to your computer and use it in GitHub Desktop.
Save mujz/38c52123104b2f26f7a179dd1e3ce194 to your computer and use it in GitHub Desktop.
Using rsync, inotify, and fswatch to sync code between 2 environments
### How it works
## rsync
# A tool that syncs your files across environments over ssh.
# When you run the command the second time, it only copies the changed files.
## inotify/fswatch
# inotify-tools is a linux file watcher and fswatch is for Mac OS. It's as simple as that.
## Put them together and you get
# A tool that watches your files for changes on one machine and updates them on the other immediately.
### How to use it
# 1. Set the env variables REMOTE_DIR (format: user@host:dir) and LOCAL_DIR (ex. /home/user/my_project)
# 2. Run the script
#!/usr/bin/env bash
set -e
trap "exit" INT
CYAN='\033[0;36m'
NC='\033[0m'
# Exclude .git directory and vim tmp files
EXCLUDE='.git|\.sw.*|.\~|4913'
# Make sure the local and remote dirs locations env vars are set
if [ -z ${REMOTE_DIR} ]; then
echo "please set the environment variable REMOTE_DIR (ex. /home/user/prj_dir)"
exit 1
fi
if [ -z ${LOCAL_DIR} ]; then
echo "please set the environment variable LOCAL_DIR (format: user@host:dir)"
exit 1
fi
# set whether to use inotifywait or fswatch depedning on which one exists
# If neither exist, exit with status 1
hash inotifywait 2>/dev/null && use_inotify=true || \
hash fswatch 2>/dev/null && use_fswatch=true || \
exit 1
if [ "${use_inotify}" = true ]; then
# watch recursilvely for file changes and deletions
# output format: HH:MM:SS - Event:Event filename
watch="inotifywait -r -m -e close_write -e delete --exclude \"${EXCLUDE}\" --format '%T - %:e %f' --timefmt '%H:%M:%S' \"${LOCAL_DIR}\""
elif [ ${use_fswatch} = true ]; then
# watch recursively for the listed events
# output format: HH:MM:SS absolute/path/to/file Event Event
watch="fswatch -txr -f '%H:%M:%S' \
-e $(echo \"${EXCLUDE}\" | sed 's/\|/\ -e\ /g') \
--event Created --event Updated --event Removed --event Renamed --event MovedFrom --event MovedTo \
\"${LOCAL_DIR}\""
fi
# print the output the watch command and sync push
eval "${watch}" | while read notification; do
echo -e "${CYAN}${notification}${NC}"
# sync the changes and deletions in the local dir with the remote dir
# and exclude the gitignored files and .git dir
rsync -aiz --delete --exclude-from "${LOCAL_DIR}/.gitignore" --exclude ".git" ${LOCAL_DIR} ${REMOTE_DIR}
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment