如何用Python持续监控文件变化?pyinotify仅触发一次通知求助
Hey there! I’ve dealt with this exact pyinotify quirk before—total bummer when it stops monitoring after the first event, right? Let’s walk through the most common causes and fixes to keep your watch running nonstop.
Common Reasons & Solutions
1. You’re Not Running a Continuous Listen Loop
The most frequent culprit is forgetting to start a persistent loop to keep listening for events. If you only call read_events() once, it’ll grab the first event and exit. Instead, use the built-in loop() method or a custom while loop.
Here’s a working example:
import pyinotify # Create a custom event handler class FileChangeHandler(pyinotify.ProcessEvent): def process_IN_MODIFY(self, event): # Your custom logic here print(f"Detected change in: {event.pathname}") # Set up the watch manager and notifier watch_manager = pyinotify.WatchManager() # Define which events to monitor (adjust masks as needed) event_mask = pyinotify.IN_MODIFY handler = FileChangeHandler() notifier = pyinotify.Notifier(watch_manager, handler) # Add your target file/directory to the watch watch_manager.add_watch("/path/to/your/target/file", event_mask) # Start the infinite monitoring loop print("Monitoring for file changes... Press Ctrl+C to stop.") notifier.loop()
2. Your File Is Being Replaced (Not Modified)
Many editors (like VS Code, Sublime) don’t edit files directly—they create a temporary file, modify it, then replace the original. This means the IN_MODIFY event won’t trigger, and your watch might lose track of the file.
Fix this by expanding your event mask to cover creation/deletion/move events:
# Include all relevant event types event_mask = pyinotify.IN_MODIFY | pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MOVED_TO # Update your handler to process these events if needed class FileChangeHandler(pyinotify.ProcessEvent): def process_IN_MODIFY(self, event): print(f"File modified: {event.pathname}") def process_IN_MOVED_TO(self, event): # Re-watch the new file if the original was replaced if event.pathname == "/path/to/your/target/file": watch_manager.add_watch(event.pathname, event_mask) print(f"Re-established watch on replaced file: {event.pathname}")
3. Unhandled Exceptions Are Killing the Loop
If your event handling logic throws an uncaught exception, it’ll crash the loop() call and stop monitoring. Always wrap your custom logic in a try-except block to keep the loop running:
def process_IN_MODIFY(self, event): try: # Your potentially error-prone logic here with open(event.pathname, "r") as f: content = f.read() print(f"Updated content length: {len(content)}") except Exception as e: print(f"Error handling event: {str(e)}")
4. Use ThreadedNotifier for Background Monitoring
If you need to run other code alongside the file watch, use ThreadedNotifier to run the monitor in a separate thread:
import time notifier = pyinotify.ThreadedNotifier(watch_manager, handler) notifier.start() # Your main program logic here while True: # Do other tasks print("Running main program tasks...") time.sleep(5) # Stop the notifier when done (you'll need a signal handler for clean shutdown) # notifier.stop()
Quick Checklist
- Confirm you’re using
notifier.loop()or a continuous while loop - Expand your event mask to cover file replacement scenarios
- Add try-except blocks in event handlers to catch errors
- Use
ThreadedNotifierif you need parallel execution
内容的提问来源于stack exchange,提问作者Artik

