-
Notifications
You must be signed in to change notification settings - Fork 72
Description
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.