I'd like to monitor a file with inotify, and trigger some code when someone changes the content (IN_MODIFY or IN_CLOSE_WRITE), but I'm running into problems where inotify stops returning events when users edit the file with their favorite tool. The file is meant to be simple (single line, no spaces, max 20 characters). I'd rather not restrict their usage, but I'm not sure how to handle different situations.
I'm using inotify and these are the events that I receive when various applications edit the file:
| Action | inotify Events |
|---|---|
touch file | IN_OPEN |
echo "data" > file | IN_MODIFY, IN_OPEN, IN_ACCESS, then IN_CLOSE_NOWRITE |
nano file (on open) | IN_OPEN |
nano file (on ^O) | IN_MODIFY, IN_CLOSE_WRITE, IN_OPEN, IN_ACCESS |
vim file (on open) | IN_OPEN, IN_CLOSE_NOWRITE |
vim file (on :w) | IN_MOVE_SELF, IN_ATTRIB, then events stop coming from this file |
gedit file (on open) | IN_OPEN, IN_CLOSE_NOWRITE, IN_ACCESS |
gedit file (on save) | IN_OPEN, IN_CLOSE_WRITE, IN_ATTRIB, then events stop coming from this file |
mv newfile file | IN_ATTRIB, then events stop coming from this file |
At one point I thought I saw gedit trigger also trigger IN_DELETE_SELF before going silent.
In the case where a user uses vim and gedit, I stop getting inotify events after the user has finished the edits. How should I deal with this?
The only thing I see in common is the IN_ATTRIB event. I suspect that when I receive the IN_ATTRIB event, I should inotify_rm_watch() that wd, and then re-create a new inotify_add_watch() based on the same path. But is that the correct approach?
Another option could be to watch the parent directory. The affected file name is included in the inotify_event::name, and so I could filter on the file of interest, and trigger off of any IN_MODIFY or IN_CLOSE_WRITE where the name matches my file of interest.
foo.txttofoo.txt~). That would mean that if you only follow the original file, you should see just a rename event on the original, and nothing on the new one. Though there looks to be only oneIN_MOVE*event in your list, but plausibly some programs might do something similar without renames (and without backup files). If you want to follow files of a particular name, you might need to follow the whole directory to catch them.