How to monitor filesystem events on files and directories on Linux

Inode notify (inotify) is a Linux kenel subsystem which provides APIs to to monitor filesystem events. Besides communicating with such APIs from proper programming languages, it is possible to take advantage of the exposed functionalities by using some explicitly designed command line tools such as inotifywait, which can be easily installed in all the major Linux distributions.

In this tutorial we see how to install and use the inotifywait utility to monitor filesystem events on Linux.

In this tutorial you will learn:

  • How to install inotifywait on some of the most used Linux distributions
  • How to use inotifywait to monitor filesystem events on files and directories
  • How to monitor a specific event
how to monitor filesystem events on files and directories on linux
How to monitor filesystem events on files and directories on Linux
Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Distribution agnostic
Software inotify-tools
Other Privileged access to your Linux system as root or via the sudo command in order to install required packages
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Installation

The inotifywait command line utility is part of the inotify-tools package, which is available in the official repositories of all the major Linux distributions. To install the package on Fedora and Fedora-based distributions, we run:

$ sudo dnf install inotify-tools



To install it on Debian and derivatives, instead, we can use the following command:

$ sudo apt install inotify-tools

The package is also available in the “Extra” Archilinux repository. We can the pacman package manager to perform the installation:

$ sudo pacman -Sy inotify-tools

Monitoring filesystem events

The inotifywait utility can be used to wait and react to filesystem events. In the simplest possible usage, we invoke the utility and pass the path of the file or the directory we want to monitor, as argument. In the example below we use the ~/.bash_profile file as an example:

$ inotifywait ~/.bash_profile
Setting up watches.
Watches established.



When executed the way we did above, the tool establishes a watched on the specified file, and exists when the first event occurs. Just as an  example, let’s attempt to read the content of the file:

$ cat ~/.bash_profile

As soon as we launch the command from another terminal window, we are notified of an “OPEN” event and inotify exits:

/home/doc/.bash_profile OPEN

If we pass a directory path as argument to the command, all files inside said directory will be monitored; not the content of sub-directories, however, since the command, by default, is not recursive. To change this behavior and monitor an entire directory tree, all we have to do is to use the -r (--recursive) option. When running the utility this way we may have to increase the maximum number of allowed watches, which can be done by writing the appropriate value to the /proc/sys/fs/inotify/max_user_watches file. Notice, however that changes to the file are not preserved on reboot. Check out this tutorial to learn how to make them permanent.

Listening to a specific event

In certain situations we may want to be notified only when some specific event occurs on a file. In such cases we can simply use the -e (short for --event) option, and pass one of the supported EVENTS as argument. Sticking to the previous example, to monitory only “modify” events on the ~/.bash_profile file, we would run:

$ inotifywait -e modify ~/.bash_profile



Since we are listening only to the “modify” event, the command will keep running if we read the content of the file, but will notify us as soon as we attempt to write on it, as when simply appending some content:

$ echo "# This is just a comment" >> ~/.bash_profile

The event is notified as expected:

/home/doc/.bash_profile MODIFY

The events we can listen to are reported in the following table, as described in the utility manual:

Event Description
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 writable 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.

Listening in “monitor” mode

In previous examples we saw how, by default, a watches established using inotifywait exists as soon as one of the monitored events occur.
If we want the command to keep listening to events, we can simply use the -m option, which is the short form of --monitor.



In the following example we establish a watch on the target file in monitor mode, than, we first read its content, than, append some content to it. Each operation involves three events, all of which are logged:

$ inotifywait -m ~/.bash_profile
Setting up watches.
Watches established.
/home/doc/.bash_profile OPEN                # The file is opened
/home/doc/.bash_profile ACCESS              # The file is read          
/home/doc/.bash_profile CLOSE_NOWRITE,CLOSE # The file is closed after being opened in read-only mode
/home/doc/.bash_profile OPEN                # The file is opened
/home/doc/.bash_profile MODIFY              # The file is modified (we appended content to it)
/home/doc/.bash_profile CLOSE_WRITE,CLOSE   # The file is closed after being opened in writable mode

Excluding files from being monitored

As we already said, the inotifywait utility can be used to listen to events on files inside a specified directory, or on a whole directory tree. In such situations we may want to avoid monitoring specific files, or explicitly include some of them. To accomplish such tasks, we can use the --exclude and --include options, respectively. Both of them take a POSIX regular expression as argument.



In the following example, we monitor all files under the ~/.config directory, except those with the “.xml” extension:

$ inotifywait -m ~/.config --exclude ".*.xml"

The --include and --exclude options match the passed expressions in case-sensitive mode; both, however, have a variant which works in case-insensitive mode: --includei and --excludei, respectively.

Conclusions

In this tutorial we learned how to install the inotify-tools package on some of the most used Linux distributions, and how to use the inotifywait command line utility to monitor events occurring on files and directories.



Comments and Discussions
Linux Forum