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
。
因此行为也可能会偏离。
下面的 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
。
因此行为也可能会偏离。