如何在RPi OS与Python中监听分区挂载/卸载通知?
问题分析与解决方案
你遇到的问题根源在于**/proc是虚拟文件系统(procfs)**,/proc/mounts这类文件的更新机制和常规磁盘文件不同:当挂载/卸载操作发生时,系统不会修改现有文件的内容,而是直接销毁旧的文件inode,重新生成一个新的inode来提供更新后的内容。
原代码仅监听IN_MODIFY事件(文件内容修改),但这种inode替换的操作不会触发该事件;同时,原watch绑定的是旧inode,新inode生成后,原watch会失效,自然无法捕获后续变化。
修正后的代码
import pyinotify import time class EventHandler(pyinotify.ProcessEvent): def process_IN_MODIFY(self, event): if event.pathname == "/proc/mounts": print(f"Mount changes detected!") # 可选:读取文件内容做进一步处理 with open("/proc/mounts", "r") as f: print(f"Current mounts (snippet):\n{f.read()[:200]}...") def process_IN_DELETE_SELF(self, event): # 当文件inode被销毁时,重新为新的/proc/mounts添加监听 if event.pathname == "/proc/mounts": print(f"Resetting watch for /proc/mounts") wm.add_watch("/proc/mounts", pyinotify.IN_MODIFY | pyinotify.IN_DELETE_SELF) # 初始化监听管理器与事件处理器 wm = pyinotify.WatchManager() handler = EventHandler() notifier = pyinotify.ThreadedNotifier(wm, handler) # 初始监听同时包含IN_MODIFY和IN_DELETE_SELF事件 wm.add_watch("/proc/mounts", pyinotify.IN_MODIFY | pyinotify.IN_DELETE_SELF) print("Watching for mount/unmount events...") notifier.start() try: while True: time.sleep(1) except KeyboardInterrupt: print("\nStopping watch...") notifier.stop() print('Done!')
关键改动说明
- 添加
IN_DELETE_SELF事件监听:当/proc/mounts的旧inode被销毁时,会触发该事件,此时我们重新为新生成的/proc/mounts文件绑定watch,确保后续变化能被捕获。 - 保留
IN_MODIFY事件:虽然procfs下这种情况很少,但可以覆盖少数直接修改文件内容的场景(如某些特殊系统操作)。 - 增加路径判断:确保只处理/proc/mounts相关的事件,避免无关文件的干扰。
额外提示
如果需要精准识别挂载/卸载的具体内容,建议在事件触发时读取/proc/mounts的完整内容,与之前保存的快照做对比,过滤出实际变化的挂载项,避免重复输出或误触发。
内容的提问来源于stack exchange,提问作者Marus Gradinaru
相关产品推荐
相关产品推荐

