Its a pretty common exercise in Linux/Unix shell programming to monitor a particular folder for file changes, typically the addiiton or change of a file. There’s a variety fo ways to do it , the more common approach is to use. In Linux, we can use the inotify interface to monitor a directory or a file. We do this by adding a watch to the directory or file. When we add a watch to a file, we can monitor it. For example, we’ll know when a process opens, modifies, reads closes, moves, or deletes the file. The major issue with inotify-tools is typically it’s not installed by default (its pare on most Linux systems,
sudo apt-get update
sudo apt-get install inotify-tools
and generally requires elevated privileges (root, sudo) to use.
A simple solution (no root required)
So below is a simple and short method that uses old school but readily available function to monitor a folder for file changes.
###############################################
# watch.sh Simple script filewatcher, awaits file changes on SOURCE_FOLDER then
# runs some eXEC_SCRIPT them to the TARGET Folder with using RSYNC .
# If permissions in TARGET folder different then Requires SSH keyless setup for file copy
###############################################
SOURCE_FOLDER=/folder/to/watch/
TARGET_FOLDER=/destination/folder/
# files to exclude from copying to new destination folder
EXCLUDE_FILE=exluded_files.txt
EXCLUDE_LIST="lastwatch,.gitignore ,watch.sh ,.git/"
#script to run when file changes occur
EXEC_SCRIPT="rsync -az --progress --exclude-from=$EXCLUDE_FILE $SOURCE_FOLDER $TARGET_FOLDER \ "
# Sleep in bewteen watch checks
POLLING_TIME=3
#if [ ! -z "$EXCLUDE_LIST" ]
EXCLUDE_LIST_LF="${EXCLUDE_LIST//,/$'\n'}" #replace command with new line
echo -en "$EXCLUDE_LIST_LF" > $EXCLUDE_FILE
echo "-----------------------------------------------------------------------"
echo WATCHING files from $SOURCE_FOLDER ..to.. $TARGET_FOLDER every $POLLING_TIME s
echo "-----------------------------------------------------------------------"
while true
do
touch ./lastwatch
sleep $POLLING_TIME
# echo -e "rsync -az --progress --exclude-from=$EXCLUDE_FILE $SOURCE_FOLDER $TARGET_FOLDER"
find $SOURCE_FOLDER -cnewer ./lastwatch -exec $EXEC_SCRIPT;
echo -e ".\c"
done
echo FINISHED copying files from $SOURCE_FOLDER ..to.. $TARGET_FOLDER
What the code does above is pretty straight forward it uses the find $SOURCE_FOLDER -cnewer ./lastwatch -exec $EXEC_SCRIPT; to match any files newer (-cnewer) that have changed since ./lastwatch and then the find command provides then executes the -exec $EXEC_SCRIPT which in this case is just a rsync sync -az --progress --exclude-from=$EXCLUDE_FILE $SOURCE_FOLDER $TARGET_FOLDER command to copy the changed files to a destination folder.
That’s it, to run the command just save the above file as something like watch.sh, and then enable its execution via chmod +x watch.sh , finally run the command in the background like ./watch.sh & or nohup ./watch.sh (if you want it to persist after you leave the terminal session)