PyInotify
PyInotify copied to clipboard
Moves are not handled properly
PyInotify keeps track of watched files by path, but the kernel tracks them by inode and PyInotify doesn't update it's internal cache when a file is moved. Hence:
#!/usr/bin/env python3 import inotify.adapters import os from threading import Thread import time from inotify.constants import IN_MOVED_FROM, IN_CLOSE_WRITE
i = inotify.adapters.Inotify()
os.system("mkdir foo") os.system("touch foo/bar") watch_file = i.add_watch("foo/bar", mask=IN_CLOSE_WRITE) watch_dir = i.add_watch("foo", IN_MOVED_FROM) print ("watch_dir = {}, watch_file={}".format(watch_dir, watch_file))
def mythread(): print ("in mythread") time.sleep(3) os.system("mv foo/bar foo/baz") os.system("touch foo/bar")
Thread(target=mythread, daemon=True).start()
for event in i.event_gen(yield_nones=False): (desc, type_names, path, filename) = event
print ("event: %s, %s, %s, %s" %(desc, type_names, path, filename))
if desc.wd == watch_dir:
time.sleep(3)
# "foo/bar" is now the new file.
print ("adding watch again")
watch_file2 = i.add_watch("foo/bar", mask=IN_CLOSE_WRITE)
Should watch foo/baz as well as foo/bar, but
./inotify_test.py mkdir: cannot create directory ‘foo’: File exists watch_dir = 2, watch_file=1 in mythread event: _INOTIFY_EVENT(wd=2, mask=64, cookie=2139762, len=16), ['IN_MOVED_FROM'], foo, bar adding watch again Path already being watched: [foo/bar]
A work around is to do a superficial remove of the old path to get it out of the cache without removing it from what is actually watched. However, if you do that, then you cannot later stop watching the original file.
I observe the same behavior. It's problematic.
This library (release on PyPI) fails to handle properly:
- rename of directories
- deletion of directories followed by re-creation
There is no active maintenance of this library. Single maintainer that lost interest, the fate of many potentially useful libraries.
I was hoping to simply use this library instead of my own, where I implemented all of that already, but didn't like the hackiness.
@rbiro-alarm , @crackwitz This issue have been fixed in commit #34 but unfortunately the pip package have not been updated since 2018.
To fix this issue you can uninstall the package with
pip3 uninstall inotify
Then install it from github.
git clone https://github.com/dsoprea/PyInotify.git
cd PyInotify
python3 setup.py install