Inotify事件监控工具
Inotify 是 Linux 内核提供的一种高效文件系统事件监控机制,用于实时检测文件或目录的变化(如创建、修改、删除等)。
核心特性
实时性:通过内核主动推送事件,避免轮询的资源消耗
细粒度监控:支持多种事件类型(如
IN_CREATE、IN_MODIFY、IN_DELETE等),可精确到单个文件或目录低开销:基于文件描述符接口,兼容
select/poll/epoll等 I/O 多路复用机制
使用场景
文件同步:如结合
rsync实现实时备份日志监控:实时跟踪日志文件更新
自动化脚本:触发文件变动后的自定义操作(如重新加载配置)
inotify服务搭建
安装
bash
# Debian/Ubuntu
sudo apt install inotify-tools
# RHEL/CentOS
sudo yum install inotify-tools语法格式
inotifywait 是 Linux 下基于 inotify 机制的文件系统监控工具,属于 inotify-tools 软件包的一部分。它可以阻塞式地等待文件系统事件(如文件创建、修改、删除等),非常适合用于编写自动化脚本。
bash
inotifywait [-hcmrq] [-e <event>] [-t <seconds>] [--format <fmt>] [--timefmt <fmt>] <file> [<file> ...]选项
| 选项 | 描述 | 示例 |
|---|---|---|
-h | 显示帮助信息 | inotifywait -h |
-m | 持续监控模式(不退出) | inotifywait -m /tmp |
-r | 递归监控目录 | inotifywait -r /var/log |
-q | 减少冗余输出 | inotifywait -q /home |
-e <event> | 指定监控的事件类型 | inotifywait -e create,delete /tmp |
-t <seconds> | 设置超时时间(秒) | inotifywait -t 60 /opt |
--format <fmt> | 自定义输出格式 | inotifywait --format '%T %w%f' /tmp |
--timefmt <fmt> | 设置时间格式 | inotifywait --timefmt '%Y-%m-%d' /tmp |
--exclude <pattern> | 大小写敏感的正则表达式排除模式 | inotifywait -r --exclude '^/tmp/backup' /tmp |
--excludei <pattern> | 大小写不敏感的正则表达式排除模式 | inotifywait -r --excludei '\.log$' /var |
--fromfile <file> | 从文件读取排除模式(每行一个) | inotifywait -r --fromfile exclude_list.txt /data |
--format占位符
| 占位符 | 描述 | 示例输出 |
|---|---|---|
%w | 监控的目录路径 | /tmp |
%f | 触发事件的文件名(目录事件为空) | test.log |
%e | 事件类型(多个事件用逗号分隔) | CREATE,MODIFY |
%T | 当前时间(需配合--timefmt使用) | 2025-06-12 14:30:00 |
--timefmt占位符
| 参数 | 说明 | 示例输出 |
|---|---|---|
%Y | 4位年份 | 2025 |
%y | 2位年份 | 25 |
%m | 月份(01-12) | 06 |
%d | 日期(01-31) | 13 |
%H | 小时(00-23) | 15 |
%M | 分钟(00-59) | 30 |
%S | 秒(00-59) | 45 |
%A | 星期全称 | Friday |
%a | 星期缩写 | Fri |
%B | 月份全称 | June |
%b | 月份缩写 | Jun |
%F | 等价于 %Y-%m-%d | 2025-06-13 |
%T | 等价于 %H:%M:%S | 15:30:45 |
%Z | 时区 | CST |
%z | 时区偏移 | +0800 |
%s | Unix时间戳(秒) | 176543210 |
%N | 纳秒(需高精度支持) | 123456789 |
-e <event>事件
| 事件名称 | 描述 |
|---|---|
access | 文件或目录被读取 |
modify | 文件内容被修改(目录的修改时间变化) |
attrib | 文件或目录的元数据(权限、所有者、时间戳等)被修改 |
move | 文件或目录被移动(源目录触发) |
move_to | 文件或目录被移动到监控目录(目标目录触发) |
create | 在监控目录内创建新文件或子目录 |
open | 文件或目录被打开 |
close | 文件或目录被关闭(无论读写模式) |
delete | 文件或目录被删除 |
umount | 包含监控项目的文件系统被卸载 |
经典案例
bash
# 监控关键文件操作(创建/修改/删除/移动)
inotifywait -e create,modify,delete,move /important/files
# 监控权限变更和属性修改
inotifywait -e attrib /sensitive/data
# 持续监控目录变化
inotifywait -mrq --timefmt '%Y/%m/%d %H:%M' --format '%T %w%f %e' -e create,modify,delete /path/to/dir
# 监控/tmp目录下的文件创建和删除事件
inotifywait -m -e create,delete /tmp
# 带时间戳的监控输出
inotifywait -m --format '%T %w%f %e' --timefmt '%F %T' /data/logs
# 递归监控/data但排除所有.git目录
inotifywait -mr --exclude '/\.git/' /data
# 监控网站目录但排除缓存和临时文件(不区分大小写)
inotifywait -mr --excludei '(cache|temp)' /var/www
# 使用排除列表文件监控
echo -e "*.tmp\n*.bak\n/tmp/old/" > exclude.txt
inotifywait -mr --fromfile exclude.txt /home/user配合rsync脚本
shell
#!/bin/bash
# filename: rsync_inotify.sh
# author: chenhuan
# version: 1.0
# date: 2025-06-13 20:29:07
# description: 时间监听同步文件
# 后台运行:nohup /bin/sh /opt/rsync_inotify.sh > /dev/null 2>&1 &
# 定义同步目录
SYNC_DIR="/data"
# 定义密码文件
PWD_FILE="/etc/rsyncd.passwd"
# 同步服务器IP
BACKUP_SERVER="192.168.148.203"
# 用户名
USER="rsync_backup"
# 模块
MODULE="backup"
inotifywait -mrq --timefmt '%Y-%m-%d %H:%M' --format '%T#%w%f' -e create,modify,move "$SYNC_DIR" | while read -r line; do
action_date=$(echo "$line" | awk -F"#" '{print $1}')
action_file=$(echo "$line" | awk -F"#" '{print $2}')
echo "[$action_date] $action_file" >>/var/log/rsync_inotify.log
if [[ -f "$action_file" ]]; then
rsync -avz "$action_file" "$USER"@"$BACKUP_SERVER"::"$MODULE" --password-file="$PWD_FILE"
# 执行同步操作
else
cd "$action_file" && rsync -avz ./ "$USER"@"$BACKUP_SERVER"::"$MODULE" --password-file="$PWD_FILE"
fi
done内核优化
bash
# max_user_watches:设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)
# max_user_instances:设置每个用户可以运行的inotifywait或inotifywatch命令的进程数
# max_queued_events:设置inotify实例事件(event)队列可容纳的事件数量。
cat >> /etc/sysctl.conf << EOF
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
EOF
sysctl -pInotify 的优缺点
优点
- 高效实时
- 基于内核事件驱动,无轮询开销(对比
cron或stat轮询)。 - 延迟极低(毫秒级响应)。
- 基于内核事件驱动,无轮询开销(对比
- 细粒度监控
- 支持多种事件类型(如文件创建、修改、删除、权限变更等)。
- 可监控单个文件或整个目录树。
- 低资源占用
- 通过文件描述符管理,适合高并发场景。
- 内核直接推送事件,减少用户态-内核态切换。
- 兼容性
- 支持
select/poll/epoll多路复用,易于集成到现有程序。
- 支持
缺点
- 内核依赖
- 需要 Linux 内核 ≥ 2.6.13(旧系统需升级)。
- 部分嵌入式设备可能不支持。
- 资源限制
- 默认监控文件数有限(通过
/proc/sys/fs/inotify/max_user_watches调整)。 - 大量监控目标时可能耗尽内存或文件描述符。
- 默认监控文件数有限(通过
- 事件丢失风险
- 内核队列溢出时可能丢失事件(需调整
max_queued_events)。 - 不保证事件的顺序性。
- 内核队列溢出时可能丢失事件(需调整
- 递归监控复杂
- 需手动处理子目录的创建/删除事件(对比
fanotify的自动递归)。
- 需手动处理子目录的创建/删除事件(对比
与其他监控工具对比
| 工具 | 原理 | 实时性 | 递归监控 | 适用场景 | 缺点 |
|---|---|---|---|---|---|
| Inotify | 内核事件驱动 | ⭐⭐⭐⭐ | 需手动 | 文件同步、日志监控、配置热更新 | 依赖内核版本,事件可能丢失 |
| Fanotify | 内核事件驱动(更强大) | ⭐⭐⭐⭐ | 自动 | 安全审计、恶意软件防护 | 需要 root 权限,配置复杂 |
Polling(如 stat 轮询) | 定期检查文件状态 | ⭐⭐ | 支持 | 兼容性要求高的简单场景 | 高延迟,高 CPU 开销 |
| Auditd | 内核审计框架 | ⭐⭐⭐ | 支持 | 安全合规、入侵检测 | 性能开销大,配置复杂 |
| eBPF + kprobes | 动态内核追踪 | ⭐⭐⭐⭐ | 支持 | 深度性能分析、调试 | 学习曲线陡峭,需高版本内核 |
