15

I'm trying to monitor my /tmp folder for changes using inotifywatch:

sudo inotifywatch -v -r /tmp

After creating couple of files (touch /tmp/test-1 /tmp/test-2), I'm terminating inotifywatch (by Ctrl-C which shows me the following statistics:

Establishing watches...
Setting up watch(es) on /tmp
OK, /tmp is now being watched.
Total of 39 watches.
Finished establishing watches, now collecting statistics.
total  attrib  close_write  open  create  filename
8      2       2            2     2       /tmp/

The output only prints the statistics, but not the files I expected (as in here or here). I tried different types of access (via cat, mktemp, etc.), but it's the same thing.

Did I miss something? It's because I'm on VPS and something has been restricted?

OS: Debian 7.3 (inotify-tools) on VPS

kenorb
  • 20,250
  • 14
  • 140
  • 164

1 Answers1

17

This is due to the way you're using inotifywatch, and the way the tool itself works. When you run inotifywatch -r /tmp, you start watching /tmp and all the files that are already in it. When you create a file inside /tmp, the directory metadata is updated to contain the new file's inode number, which means that the change happens on /tmp, not /tmp/test-1. Additionally, since /tmp/test-1 wasn't there when inotifywatch started, there is no inotify watch placed on it. It means that any event which occurs on a file created after the watches have been placed will not be detected. You might understand it better if you see it yourself:

$ inotifywatch -rv /tmp &
Total of n watches.
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

If you have enabled the tracing mechanism on inotify_add_watch(2), the last command will give you the number of watches set up by inotifywatch. This number should the same as the one given by inotifywatch itself. Now, create a file inside /tmp and check again:

$ inotifywatch -rv /tmp &
Total of n watches.
$ touch /tmp/test1.txt
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n

The number won't have increased, which means the new file isn't watched. Note that the behaviour is different if you create a directory instead :

$ inotifywatch -rv /tmp &
Total of n watches.
$ mkdir /tmp/test1
$ cat /sys/kernel/debug/tracing/trace | grep inotifywatch | wc -l
n + 1

This is due to the way the -r switch behaves:

-r, --recursive: [...] If new directories are created within watched directories they will automatically be watched.

Edit: I got a little confused between your two examples, but in the first case, the watches are correctly placed because the user calls inotifywatch on ~/* (which is expanded, see don_crissti's comment here). The home directory is also watched because ~/.* contains ~/.. Theoretically, it should also contain ~/.., which, combined with the -r switch, should result in watching the whole system.

However, it is possible to get the name of the file triggering a create event in a watched directory, yet I'm guessing inotifywatch does not retrieve this information (it is saved a little deeper than the directory name). inotify-tools provides another tool, called inotifywait, which can behave pretty much like inotify-watch, and provides more output options (including %f, which is what you're looking for here) :

inotifywait -m --format "%e %f" /tmp

From the man page:

--format <fmt> Output in a user-specified format, using printf-like syntax. [...] The following conversions are supported:

%f: when an event occurs within a directory, this will be replaced with the name of the file which caused the event to occur.

%e: replaced with the Event(s) which occurred, comma-separated.

Besides, the -m option (monitor) will keep inotifywait running after the first event, which will reproduce a behaviour quite similar to inotifywatch's.

John WH Smith
  • 15,500
  • 6
  • 51
  • 62
  • 1
    `.bashrc` in the example @ `serverfault` does not appear in the stats because the user monitors its home directory recursively but because `path/.*` is expanded and as a result a watch is set for all the .files under `path/` (`.bashrc` included). The command used by the OP will never output file names because the watches are set for `/tmp` and any subdirectories therefore statistics will pertain only to `/tmp` and its subdirectories (i.e. you will see files have been accessed/moved/etc but it won't tell you their names). – don_crissti Oct 29 '14 at 13:39
  • @don_crissti Oops, I mixed up the two examples given by the OP. I edited my answer, thanks! – John WH Smith Oct 29 '14 at 13:49
  • Thanks, it was useful. Here is my command to show content of all newly created test* files in `/tmp`: `inotifywait -m --format "%f" /tmp | grep --line-buffered ^test | xargs -L1 -I% sudo cat /tmp/% 2> /dev/null`. – kenorb Oct 29 '14 at 14:00
  • Also: "_It means that any event which occurs on a file created after the watches have been placed will not be detected._" Any event (even the file creation) WILL be detected because a watch is ALREADY set for the containing directory and this is reflected in the statistics for that particular directory. See `inotifywatch` output in the OP question: the 2 `create` events are there (so they are detected) but since `inotifywatch` watches a directory (+any subdirectories) the statistics pertain only to that/those directories. – don_crissti Oct 29 '14 at 15:19
  • @don_crissti Even though an event is detected, it does not come from the file itself, but its parent directory: *"any event which occurs **on** a file"*. – John WH Smith Oct 29 '14 at 18:07
  • 1
    I don't think we're on the same wavelength here... `man inotify`: `When a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.` Also, `man inotifywatch` is clear about which events are being watched: > `EVENTS` > ... _A watched file **or a file within a watched directory** was accessed/closed/open/etc_ (means including events _"which occur on a file"_). Events for a file created after setting the watch on parent dir WILL be detected & reflected in `inotifywatch` stats (it will NOT mention for which files those events occured). – don_crissti Oct 29 '14 at 20:35
  • @don_crissti My bad, I didn't see that one. I must have been too focused on the `-r`ecursive aspect of the tools, and not enough on that particular behaviour of the API. – John WH Smith Oct 29 '14 at 21:33