====== BASH - Directories - Monitor a directory for changes - Using inotifywait ======
===== Install inotify-tools =====
sudo apt install inotify-tools
----
===== Test inotifywait =====
In a shell enter:
while true; do
res=`inotifywait -r thedirtowatch/ --format %f`;
echo "RESULT=$res";
done
returns:
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
**NOTE:** The **--format %f** refers to the filename in the event.
* **-r, --recursive**: Watch all sub-directories of any directories passed as arguments. Watches will be set up recursively to an unlimited depth.
* Symbolic links are not traversed. Newly created sub-directories will also be watched.
See http://manpages.ubuntu.com/manpages/focal/man1/inotifywait.1.html for options.
----
In a 2nd shell, go to that directory being watched.
cd thedirtowatch/
touch test1
**NOTE:** Back on the 1st shell this should show you output:
RESULT=test1
----
===== Only listen for certain events =====
Change the inotifywait to the following:
while true; do
res=`inotifywait -q -e create, open, close, modify, moved_to, moved_from -r thedirtowatch/ --format '%e %f'`;
echo "RESULT=$res\n";
done
**NOTE:** The additional **-e** option can be added to the inotifywait to only listen for certain events.
Events include:
* **access**: A watched file or a file within a watched directory was read from.
* **modify**: A watched file or a file within a watched directory was written to.
* **attrib**: The metadata of a watched file or a file within a watched directory was modified.
* This includes timestamps, file permissions, extended attributes etc.
* **close_write**: A watched file or a file within a watched directory was closed, after being opened in writeable mode.
* This does not necessarily imply the file was written to.
* **close_nowrite**: A watched file or a file within a watched directory was closed, after being opened in read-only mode.
* **close**: A watched file or a file within a watched directory was closed, regardless of how it was opened.
* Note that this is actually implemented simply by listening for both **close_write** and **close_nowrite**, hence all close events received will be output as one of these, not **CLOSE**.
* **open**: A watched file or a file within a watched directory was opened.
* **moved_to**: A file or directory was moved into a watched directory.
* This event occurs even if the file is simply moved from and to the same directory.
* **moved_from**: A file or directory was moved from a watched directory.
* This event occurs even if the file is simply moved from and to the same directory.
* **move**: A file or directory was moved from or to a watched directory.
* Note that this is actually implemented simply by listening for both **moved_to** and **moved_from**, hence all **close** events received will be output as one or both of these, not **MOVE**.
* **move_self**: A watched file or directory was moved.
* After this event, the file or directory is no longer being watched.
* **create**: A file or directory was created within a watched directory.
* **delete**: A file or directory within a watched directory was deleted.
* **delete_self**: A watched file or directory was deleted.
* After this event the file or directory is no longer being watched.
* Note that this event can occur even if it is not explicitly being listened for.
* **unmount**: The filesystem on which a watched file or directory resides was unmounted.
* After this event the file or directory is no longer being watched.
* Note that this event can occur even if it is not explicitly being listened to.
The **--format** option is changed to include showing **%e** which is the actual event. Obviously change as needed.
The **-q** option is to not show too much output.
See http://manpages.ubuntu.com/manpages/focal/man1/inotifywait.1.html for options.
----
===== Using monitor mode =====
Instead of running in a **while true; do** loop, an alternative is to use monitor mode:
inotifywait -m thedirtowatch/ -e create -e moved_to |
while read dir action file; do
echo "The file '$file' appeared in directory '$dir' via '$action'"
# do something with the file.
done
**NOTE:** The **--format %f** refers to the filename in the event.
* **-m, --monitor**: Instead of exiting after receiving a single event, execute indefinitely.
* The default behavior is to exit after the first event occurs.
See http://manpages.ubuntu.com/manpages/focal/man1/inotifywait.1.html for options.
----
===== Using a BASH Script =====
#!/bin/bash
#
# Monitor the input directory and if any change occurs run the provided command:
#
# Usage:
# after-change.sh /tmp ls -al %f
if [ $# -lt 3 ]; then
echo "Usage: $0 dir cmd "
exit 1
fi
which inotifywait 2>&1 >/dev/null
if [ "$?" == "1" ]; then
echo "ERROR: inotifywait not installed."
exit 1
fi
dir=$1
shift
cmd=$1
shift
options=$*
inotifywait -q -r -m $dir $options
eval $cmd
----
===== References =====
http://manpages.ubuntu.com/manpages/focal/man1/inotifywait.1.html