How to run a command when a directory's contents are updated?

If you have inotify-tools installed you can use inotifywait to trigger an action if a file or directory is written to:

#!/bin/sh
dir1=/path/to/A/
while inotifywait -qqre modify "$dir1"; do
    /run/backup/to/B 
done

Where the -qq switch is completely silent, -r is recursive (if needed) and -e is the event to monitor, in this case modify. From man inotifywait:

modify
A watched file or a file within a watched directory was written to.

Try entr command-line tool which can run arbitrary commands when files change. Since 2.9 release, a directory watch option (-d) was added to react to events when a new file is added to a directory.

Example to run the utility if a new file is added to the project:

$ while true; do
> echo src/* | entr -d your_command
> done

In directory watch mode the parent directory of each file is implicitly added to the watch list.

The only implication of this is that if a new file appears it must exit to allow an external shell loop to rescan the file system.

Here is the version without a directory watch option:

$ while true; do
> echo src/* src | entr your_command
> done

Here is a simpler example depending on your needs:

$ ls -d * | entr sh -c 'rsync -vuar A B'

Check: eradman.com/entrproject website for more details.


Strictly speaking, if someone drops a file and very quickly removes it, you might miss it. The use of inotify (under Linux, or a similar feature under other unices) makes the window of risk small.

If you can mount the filesystem of your choice on that directory (I realize this may not be an option), you can put one that records all file versions, for example copyfs.