Ubuntu inotify 在虚拟机中的使用指南
一 安装与验证
- 在虚拟机中安装工具集:sudo apt update && sudo apt install inotify-tools。inotify 是 Linux 内核特性,无需额外内核配置,安装后即可使用命令行工具 inotifywait 与 inotifywatch。
- 验证内核支持:ls -l /proc/sys/fs/inotify,能看到 max_queued_events、max_user_instances、max_user_watches 三个文件即表明支持。
- 快速测试:inotifywait -m -e create,modify,delete /tmp 观察事件输出。
二 基本用法
- 持续监控目录并输出事件:inotifywait -m -e create,modify,delete /path
- 递归监控并自定义输出格式:inotifywait -m -r -e create,modify,delete,moved_to,moved_from --format ‘%w%f %e’ /path
- 统计类监控(60 秒汇总):inotifywatch -m -t 60 -r /path
- 将事件写入日志:inotifywait -m -e create,modify,delete /path >> /var/log/inotify.log 2>&1
- 常用事件类型:create、modify、delete、moved_to、moved_from、attrib、close_write 等。
三 虚拟机场景的挂载与路径选择
- 监控虚拟机“内部磁盘”路径:直接对 /home、/var/www 等路径使用 inotifywait/inotifywatch 即可,行为与物理机一致。
- 监控“宿主机共享目录”(如 VirtualBox 共享文件夹、VMware 共享目录)时,inotify 通常可用,但事件可能受共享机制影响(如延迟、事件粒度变化)。建议优先把需要强一致事件的应用放在虚拟机内部磁盘;若必须监控共享目录,务必充分测试并评估延迟与丢失风险。
- 权限要求:运行 inotify 的用户需要对目标目录具备读/执行权限(监控写入事件通常还需对父目录有执行权限)。
四 生产化与常见故障处理
- 作为服务常驻:创建 systemd 单元(示例)
- /etc/systemd/system/inotify-monitor.service
[Unit]
Description=Inotify File System Monitor
After=network.target
[Service]
ExecStart=/usr/bin/inotifywait -m -r /path --format ‘%w%f %e’ --timefmt ‘%Y-%m-%d %H:%M:%S’
Restart=always
User=your_username
[Install]
WantedBy=multi-user.target
- 启用:sudo systemctl enable --now inotify-monitor.service
- 调优内核参数(/etc/sysctl.conf 或 /etc/sysctl.d/99-inotify.conf):
- fs.inotify.max_user_watches=524288
- fs.inotify.max_user_instances=1024
- fs.inotify.max_queued_events=16384
- 应用:sudo sysctl -p
- 常见报错与处理:
- “inotify watch limit reached”:增加 max_user_watches 并减少一次性监控的路径/文件数量。
- 事件未触发或延迟:确认监控路径正确、权限充足;共享目录场景建议改为内部磁盘或增加重试/去抖逻辑。
- 大量事件导致 CPU 升高:优化监控范围(避免 /**)、合并事件处理、使用队列/批处理、必要时改用更高效的事件聚合方案。
五 实用脚本示例
- 实时记录创建/修改/删除事件到日志
#!/usr/bin/env bash
LOG=“/var/log/inotify.log”
DIR=“/data”
/usr/bin/inotifywait -m -r -e create,modify,delete,moved_to,moved_from --format ‘%T %w%f %e’ “$DIR” >> “$LOG” 2>&1
- 简单“rsync 增量同步”触发(示例思路)
#!/usr/bin/env bash
SRC=“/data”
DST=“user@192.0.2.10::backup”
PASS=“/etc/rsync.pass”
/usr/bin/inotifywait -mrq -e close_write,create,delete,attrib “$SRC” | while read f; do
rsync -a --delete --password-file=“$PASS” “$SRC/” “$DST/”
done
提示:生产环境建议增加错误重试、去抖(防抖动)、仅同步必要子目录、以及日志轮转(如 logrotate)。