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.
Best Answer
inotify
is used to monitor files an directory by their inode, not by their name. When the file is rotated, its content does not change any longer (except for a short period, until the daemons are reloaded so that they use the newly created log file)AFAIK,
tail -f
uses the inotify system, so it won't help. But if you have a working solution withtail -f
then usetail --follow=name
(ortail -F
) if this is supported by your version oftail
(POSIX tail does not support this).tail
will then monitor the file identified by its filename. Here is an excerpt of the man page:[update]
Example of use:
Because of the pipe, the while loop executes in a sub-process, which may cause you troubles if you want to modify variables outside the loop. If you use
bash
, you may want to use this alternative syntax which does not have this undesirable effect (but is less readable):