Using inotify to monitor the filesystem

It always happens that as soon as you have created or changed a particular file, you want to start compiling, generate an archive, or upload the file to a server. Previously you turned to some sort of so-called "busy waiting" tool. Now the inotify tools accomplish the task much more conveniently and elegantly [1].

A busy waiting tool is a program that runs in an endless loop, repeatedly calling up the same information. An example would be a script that monitors the contents of a directory. The program compares the information with previously collected data and triggers when they are different. However, this process is ineffective. In the worst case scenario, it can also damage the data storage device.

It would be much better if monitoring was automated. The kernel could then use a special interface to notify all of the programs that are waiting for a change to a file. The Amiga filesystem contained this technique. Under Linux, there is a corresponding function by the name of inotify (a name that was created by combining "inode" with "notify"). Linux uses inotify for certain entries in the filesystem.

With inotify, you select options to determine what changes to the files will be communicated by the kernel and how. All of the changes trigger events (see Table 1 for an overview). You should pay careful attention to the syntax that is actually used – it can occasionally differ between programs, often times with regard to the use of lowercase and uppercase. The man pages for the programs contain instructions for dealing with errors. With SELF events, the monitored file ceases to exist after the message. This normally ends the monitoring process.

Table 1

iNotify Events

Abbreviation Format
ACCESS Access to the file(s)
ATTRIB Metadata is modified
CLOSE_WRITE File for writing closed
CLOSE_NOWRITE Write-protected file closed
CREATE New file set up
DELETE File deleted
DELETESELF Monitored directory deleted
MODIFY File modified
MODIFYSELF Monitored directory modified
MOVEDFROM File moved from the monitored directory
MOVEDTO File moved to the monitored directory
OPEN File opened

The inotify man page documents the internal interface. You can call this via man 7 inotify . Regular users do not have direct access to events. Instead, a series of tools exists to help you evaluate the corresponding information in the shell and in scripts. The most important of these tools include:

  • inotify tools : Contains inotifywait and inotifywatch , which are two tools used for simple tasks.
  • iWatch : A very easy-to-use tool.
  • fswatcher : A complex tool with many functions.
  • inotail : A version of tail that is controlled by inotify. Used as an alternative to the tail -F <File> call.
  • Fsniper : An inotify monitor with complex syntax and controlled through configuration.
  • Watchman : An inotify monitor controlled through configuration and has multitude of functions.
  • Direvent : The GNU compatible version, not dependent on a particular system.

This toolset can be expanded with other programs that offer similar functions. Additional applications like cron (incron ), as well desktop search engines like Beagle, Strigi, and Recoll, get informed by inotify when new files are created or changes have been made to existing files so that these can be indexed.

Direvent goes further than the typical inotify program. This GNU program can use both inotify and other mechanisms to detect changes in the filesystem. Having said this, Direvent can only be used via a configuration file and is therefore not suitable for use on the command line or in scripts.

inotify Tools

The inotify tools are suitable for use on the command line and in scripts. inotifywait and iWatch are the best here.

With inotifywait , you define the files to monitor and the events that should be evaluated. As soon as a relevant situation occurs, it terminates, and a script or a shell function executes the next command. This command then calls the desired action. Normally, inotifywait is used in a loop so that it can react to as many events as possible.

Listing 1 shows a typical script for this tool. The modify command monitors the file that the first argument, $1 , has designated for changes. The advantage to this method is that a random number of actions execute when the event occurs. The actions here involve making an index and, if applicable, the creation of a glossary.

Listing 1

inotifywait_example.sh

#!/bin/bash
while date; do
  inotifywait -e modify "$1"
  makeindex -g -s k+g2.ist "${1%%.*}.idx"
  nice xelatex "$@"
done

The Bash routines use the "${1%%.*}.idx" parameter in order to generate the index file name from the name of the file that is being monitored. The file extension will be .tex . After completing the makeindex script, the source text gets recompiled. There is absolutely no error control in this script due to its pared down simplicity. As a result, it doesn't offer any options for doing things like checking the entry files or preventing a makeindex from crashing should an error occur.

Options

There are a number of options that can precisely control the behavior of inotifywait . For example, the options -e <event> and --event <event> limit the type of events that the tool observes. If nothing is specified here, then inotifywait evaluates all of the results. Both the -t <time> and --timeout <time> options can indicate the wait time for the event in increments of seconds. Once this time period has passed, the program will finish even if the event has not occurred.

The -r , or --recursive , option monitors the directories plus all of the subdirectories. You should be cautious about using this option. For one thing, editing accidentally could cause unwanted changes. Also, administering deep branches of the directory tree could take up additional resources.

The @<exception(n)> option ignores the designated file(s) during monitoring. This makes sense, especially for automatically generated files, as is the case, for example, with backups. The --exclude <pattern> and --excludei <pattern> options work in a similar fashion. They define patterns for the file names that should be ignored. The second option indicates that the differences between capitalization are ignored.

The --fromfile <file> option defines the files that are to be modified by referencing the file and the paths. The -m (--monitor ) option makes sure that the program does not terminate but instead continues to work until an external signal comes in, for example, kill <PID> .

inotifywatch

inotifywatch , another inotify tool, works similarly to inotifywait except that it only collects information. It does not execute actions. The options in the program are almost the same as those in inotifywait . inotifywatch is primarily useful for identifying problems and getting an overview of what is currently happening in a filesystem or directory.

iWatch

Another more straightforward possibility for starting a command or a script, which can then be used to execute multiple commands, comes in the form of the iWatch tool [2]. It was developed with an eye for simplicity. Listing 2 shows the syntax for the command. Ordinarily it will not be necessary to enter this set of characters. UTF-8 is preset.

Listing 2

Running iWatch

$ iwatch -c "command line" [-C character set] [-e Event]...

If you designate command lines as an argument of -c and the lines contain empty spaces, then you will need to enclose these with single quotation marks. The single quotation marks prevent shell functions from expanding, whereas double quotation marks permit expansion. The quotation marks also make it possible to use complex command lines with individual commands separated with semicolons (; ). Interestingly enough, the possibility of accessing certain parts of the event also exists here. For example, the place holder %e stands for the name of the event and %f for the path and name of the triggering file.

Listing 3 shows a simple example that uses iWatch . By using *.adoc , each modification to the ASCIIDOC source texts triggers a new processing event. The program does this by recompiling the "master" file route5-2016.adoc with a2x .

Listing 3

Example using iWatch

$ iwatch -c "a2x -v -a lang=en -f pdf -dbook route5-2016.adoc; date" -e modify *.adoc &

The -r option causes iWatch to work recursively. Using -d , you switch the program into daemon mode, similar to inotifywait -d or inotifywait -m . In this mode, it is a configuration file that essentially controls the behavior of the program. With -t , you activate a list of positive filter functions. The iWatch tool evaluates the list when monitoring the files.

While the workings of iWatch are simple, there are two downsides. Since the program is written in Perl, you need to resolve a number of dependencies. Practically speaking, this means that conflicts regularly occur among the versions. In these situations, the only thing to do is to uninstall and remove all of the dependencies and then reinstall the program. The other downside is that iWatch does not have a man page. Instead, the option -h takes you to extensive help.

You will find complete documentation of this program on the homepage [3]. There you will also learn how to define the files that should not deliver a trigger by using the -x <Exception(n)> and -X <Pattern> options.

Noteworthy

The number of monitored files supported by the kernel defines a value in the pseudo file /proc/sys/fs/inotify/max_user_watches . You will often find that the default values are quite low, 8,192 being a common number. You can easily exceed this limit if you perform test monitoring on a home directory that is somewhat full (Listing 4, Line 1 to 4). However, you can to adjust the value at any time using root rights (Listing 4, line 7).

Listing 4

Maximum notifications

01 $ inotifywatch -v -t 60 -r ~
02 Establishing watches...
03 Setting up watch(es) on ~
04 Failed to watch ~; upper limit on inotify watches reached!
05 $ cat /proc/sys/fs/inotify/max_user_watches
06 8192
07 $ echo 16384 | sudo tee /proc/sys/fs/inotify/max_user_watches
08 16384
09 $ cat /proc/sys/fs/inotify/max_user_watches
10 16384

When configuring programs like incron , it makes sense to proceed with caution. Tools like this are frequently used for monitoring larger directory trees. If you do not take extreme care, it is possible that endless loops may occur since incron deposits results in files that are located in monitored regions. In the worst case scenario, these kinds of loops can even crash a system.