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)