simple script to watch for file changes on Linux

22 Mar 2023 | simple script to watch for file changes on Linux |

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)

Leave a Reply