python 看门狗文件 mod 通知

python watchdog file mod notification

下面的 python 代码是我第一次尝试在文件被修改时发出通知,但是当文件被更改时没有任何反应。

我错过了什么?

#!/usr/bin/python3

import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler


class MyHandler(FileSystemEventHandler):
    def on_modified(self, event):
        print('file changed')


if __name__ == "__main__":
    event_handler = MyHandler()
    observer = Observer()
    observer.schedule(event_handler, path='/Users/jeff/smb/storage/wsjt-x/wsjtx_log.adi', recursive=False)
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

注意:我发现此代码使用 Linux 效果很好。我在 macOS Big Sur 上遇到了问题。

在评论中澄清您的环境后,以下 3 种方法之一可能会解决您的问题。

重现:在Linux

上观看本地文件

运行 在一个 shell A 中,同时使用另一个 shell B 添加到观察到的文件 so.md 中,例如:

echo "---" >> so.md 

结果如下:

python3 so_watchdog.py so.md
file changed <FileModifiedEvent: event_type=modified, src_path='so.md', is_directory=False>
file changed <DirModifiedEvent: event_type=modified, src_path='', is_directory=True>

这是您的脚本的略微修改版本(请参阅评论):

#!/usr/bin/python3

import time
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler


class MyHandler(FileSystemEventHandler):
    def on_modified(self, event):
        print('file changed', event)  # added event to see the difference of two events for a single modification


if __name__ == "__main__":
    if len(sys.argv) < 2:
       file = '/Users/jeff/smb/storage/wsjt-x/wsjtx_log.adi'
    else:
       file = sys.argv[1]
    # below only added the file as path
    event_handler = MyHandler()
    observer = Observer()
    observer.schedule(event_handler, path=file, recursive=False)
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

注意:这是在 Linux 上使用本地文件测试的。

正在观看共享文件 (CIFS/SMB)

由于您的路径 /Users/jeff/smb/storage/wsjt-x/wsjtx_log.adi 包含 smb 我假设,您正在使用 SMB (Server Message Blocks) 在安装的共享网络位置上观看文件协议,也称为 CIFS(通用 Internet 文件系统)。

那就请按照官方文档,About using watchdog with CIFS:

When you want to watch changes in CIFS, you need to explicitly tell watchdog to use PollingObserver, that is, instead of letting watchdog decide an appropriate observer like in the example above, do:

from watchdog.observers.polling import PollingObserver as Observe

所以你的导入语句需要修改。

在 MacOS 上本地观看文件

对于 MacOS,使用的底层文件系统事件 API 是 FSEvents or FreeBSD's kqueue, instead of Linux's inotify

因此行为也可能会偏离。