Skip to content

Moves are not handled properly #97

@rbiro-alarm

Description

@rbiro-alarm

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions