Kaki
Kaki

Reputation: 93

Pyinotify / Watchdog triggers a modify event twice on one edit

I am trying to start a python script everytime is a certain file modified. To be accurate, I have a device on Raspberry Pi's serial ports which writes data into a text file (test.txt) . I have tried both tools - Watchdog / Pyinotify. Everytime the file is modified (triggers event Watchdog: on_modified / Pyinotify: IN_MODIFY), it makes duplicate trigger. I have tried every other method, even IN_CLOSE_WRITE as some people suggest, but this doesn't work at all. Does someone know, how can just a single event be triggered on one file update?

My code using Pyinotify (a bit edited tutorial file):

import pyinotify,subprocess
def onChange(ev):
    cmd = ['/usr/bin/env', 'python', 'doThisFile.py', ev.pathname]
    subprocess.Popen(cmd).communicate()
wm = pyinotify.WatchManager()
wm.add_watch('/home/pi/test.txt', pyinotify.IN_MODIFY, onChange)
notifier = pyinotify.Notifier(wm)
notifier.loop()

or Watchdog:

#!/usr/bin/python
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import subprocess
class MyHandler(FileSystemEventHandler):
    def on_modified(self, event):
        subprocess.call("/home/pi/doThisFile.py")
        print("Code started")
if __name__ == "__main__":
    event_handler = MyHandler()
    observer = Observer()
    observer.schedule(event_handler, path='.', recursive=False)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

Upvotes: 2

Views: 3913

Answers (3)

Cargo23
Cargo23

Reputation: 3189

The 2 events that you are getting are:

  1. The file was modified
  2. The directory was modified

If you run the demo code and then in a touch a file in the directory being watched, you'll see the following output:

2022-11-04 10:28:45 - Modified file: ./test
2022-11-04 10:28:45 - Modified directory: .

Upvotes: 0

user2147549
user2147549

Reputation: 1

This probably because of the text editor which was used for editing your source code. solution: calculate the time between 2 events, for example, If the events trigger too frequently, exit the handler from one of the events.

class SubEventHandler(FileSystemEventHandler):
    def __init__(self):
        self._time0 = self.getTime()
    def on_modified(self, event):
        time1 = self.getTime()
        if (time1 - self._time0) < 5:
            exit(0) # not sure it will exit properly

Upvotes: 0

xabush
xabush

Reputation: 877

I was facing the same issue while using pyinotify. But changing IN_MODIFY to IN_CLOSE_WRITE solved the issue. You can get more info from this answer

Upvotes: 1

Related Questions