inotify is a Linux kernel subsystem that acts to extend filesystems to notice changes to the filesystem, and report those changes to applications. It replaces an earlier facility, dnotify, which had similar goals.
Last time I focused on the functionality of
inotifywait command which can be used by shell to wait for a certain event and then perform other functions, but today we will see some uses of incron.
This program is an “inotify cron” system. It consists of a daemon and a table manipulator. You can use it a similar way as the regular cron. The difference is that the inotify cron handles filesystem events rather than time periods.
Why to use incron
incron provides a simple way how to solve many and many various situations. Everytimes when something depends on file system events it’s a job for incron.
Here you can see a few examples where incron is a good solution:
- notifying programs (e.g. server daemons) about changes in configuration
- guarding changes in critical files (with their eventual recovery)
- file usage monitoring, statistics
- automatic on-crash cleanup
- automatic on-change backup or versioning
- new mail notification (for maildir)
- server upload notification
- installation management (outside packaging systems)
Incron is present as a package in Debian and Ubuntu to install it just run
aptitude install incron
incron is very similar in concept and usage to using cron, as the interface is a clone of it.
Each user who is allowed to use incron may use the incrontab command to view, or edit, their rule list. These rules are processed via the daemon, and when a match occurs the relevant command is executed.
To list the current rules you’ve got defined run “incrontab -l“, and to edit them use “incrontab -e“. If you do that just now you’ll receive the following error message:
rt:~# incrontab -l user 'root' is not allowed to use incron
This error may be fixed in one of two ways:
Allow the root user to make use of incron: By editing /etc/incron.allow, adding ‘root’ to it.
Allowing all local users the ability to use incron: By removing the file /etc/incron.allow.
The user table rows have the following syntax (use one or more spaces between elements):
[Path] [mask] [command]
- Path is a filesystem path (each whitespace must be prepended by a backslash)
- mask is a symbolic (use commas for separating symbols) or numeric mask for events
- command is an application or script to run on the events
The full list of supported flags for mask include:
- IN_ACCESS File was accessed (read)
- IN_ATTRIB Metadata changed (permissions, timestamps, extended attributes, etc.)
- IN_CLOSE_WRITE File opened for writing was closed
- IN_CLOSE_NOWRITE File not opened for writing was closed
- IN_CREATE File/directory created in watched directory
- IN_DELETE File/directory deleted from watched directory
- IN_DELETE_SELF Watched file/directory was itself deleted
- IN_MODIFY File was modified
- IN_MOVE_SELF Watched file/directory was itself moved
- IN_MOVED_FROM File moved out of watched directory
- IN_MOVED_TO File moved into watched directory
- IN_OPEN File was opened
The mask may additionaly contain a special symbol IN_NO_LOOP which disables events occurred during processing the event (to avoid loops).
The command may contain these wildcards:
- $$ – a dollar sign
- $@ – the watched filesystem path (see above)
- $# – the event-related file name
- $% – the event flags (textually)
- $& – the event flags (numerically)
/tmp/spool IN_CLOSE_WRITE /usr/local/bin/run-spool $@/$#
This says “Watch /tmp/spool, and when an IN_CLOSE_WRITE event occurs run /usr/local/bin/run-spool with the name of the file that was created”.
This small script backup all files in the etc and myProject directory.
#!/bin/sh # Create a inotify backup dir (if not exists) # mkdir /var/backups/inotify # Make a copy off the full path and file # cp -p --parents $1 /var/backups/inotify # move the file to a file with datetime-stamp # mv /var/backups/inotify$1 /var/backups/inotify$1_`date +'%Y-%m-%d_%H:%M'
Make the file executable for root
chmod 755 /root/inotify.sh
/etc IN_CLOSE_WRITE,IN_MODIFY /root/inotify.sh $@/$# /home/andries/myProject IN_CLOSE_WRITE /root/inotify.sh $@/$#
So every time a file is wrote in the watched directory it’s also saved in the given directory.