如何获取触发文件/文件夹事件的进程PID?C语言inotify技术问询
inotify监控目录时获取触发进程PID的方案
inotify本身无法直接返回触发事件的进程PID,因为它的核心事件结构体struct inotify_event里没有包含进程ID字段。但可以通过以下几种间接方式实现需求:
1. 结合/proc文件系统实时扫描
当inotify触发创建/修改事件时,立刻遍历/proc目录下的进程:
- 检查每个进程的
/proc/[pid]/fd符号链接,查找是否有指向被监控目录或目标文件的描述符 - 或者验证
/proc/[pid]/cwd(进程当前工作目录)是否为被监控目录,针对文件创建操作,进程大概率处于该目录下 - 注意:这种方法存在时间窗口缺陷——进程可能在事件触发后迅速关闭文件或切换目录,导致扫描不到。可以通过过滤最近活跃的进程(比如按
/proc/[pid]/stat的stime字段排序)来提升命中率。
2. 使用auditd审计系统
通过auditd的规则追踪文件系统操作,它会完整记录触发操作的进程PID:
- 以root权限添加审计规则,例如:
auditctl -w /your/monitor/path -p rwxa,其中rwxa对应读、写、执行、属性变更操作 - 事件发生时,auditd会在
/var/log/audit/audit.log中生成包含PID、操作类型、路径的日志条目 - 在inotify触发事件后,读取最新的audit日志,通过路径匹配提取对应的PID
- 优势:准确性高,无时间窗口问题;劣势:需要root权限,依赖auditd服务运行。
3. 基于eBPF的实时跟踪(推荐)
利用eBPF挂钩文件系统相关的系统调用(如openat、mkdir、write),在系统调用层面直接获取PID和操作路径:
- 编写eBPF程序,在syscall入口或出口处捕获目标路径的操作,记录进程PID和事件类型
- 可以将eBPF程序的输出与inotify事件做关联,或者直接用eBPF替代inotify完成监控+PID获取的全流程
- 优势:高效、实时,无时间窗口问题;劣势:需要内核版本≥4.15(支持现代BPF特性),要求具备一定的eBPF开发基础。
4. 脚本层面的局限性方案(仅适用于已知进程)
如果是在脚本环境中使用inotifywait,可以结合进程定位工具:
- 先通过
pgrep等工具获取已知操作进程的PID,再用inotifywait --pid <pid>监控,确保只响应该进程触发的事件 - 但这种方法无法应对未知进程的操作,仅适用于特定场景。
内容的提问来源于stack exchange,提问作者LinOm
相关产品推荐
相关产品推荐

