inotifywait 命令详解
更新时间:2026-09-17。「一个命令一个文档」系列,属于文件与目录族。它基于内核 inotify 机制做事件驱动的文件变化监控,是配置热重载、日志管道、自动构建脚本的常用积木。
一、常用法
bash
inotifywait app.conf # 阻塞等一次事件后退出(默认)
inotifywait -m app.conf # monitor 持续监控,不退出
inotifywait -m -r /etc/nginx # 递归监控整个目录
inotifywait -m -e create,modify,delete dir # 只关心指定事件
inotifywait -m -q -e close_write --format '%w%f %e' file| 选项 | 作用 |
|---|---|
-m | monitor,持续输出事件(脚本循环必备) |
-r | 递归监控子目录 |
-e | 限定事件:create/modify/delete/moved_to/moved_from/close_write/access |
--format | 控制输出字段:%w目录 %f文件 %e事件 %T时间 |
-q/-qq | 精简输出,-qq 只打事件行 |
二、常用事件与"编辑器存盘"的坑
modify:内容被写(一次保存可能触发多次 modify,Vim 等还会走"写临时文件+rename")。close_write:文件以写方式打开后被关闭——监听"写完了"比监听 modify 更稳,避免处理半成品。create/delete/moved_to/moved_from:新建、删除、移入、移出。- Vim/IDE 保存配置常是"写临时文件再 rename 覆盖",监控固定 inode 可能丢事件;监控目录的 create/close_write/moved_to 更可靠。
三、典型脚本:配置变化自动 reload
bash
#!/bin/bash
while inotifywait -e close_write /etc/app/config.yaml; do
systemctl reload app # 文件写完才 reload
done热重载、entr、Webpack dev server、同步工具(lsyncd)底层都是同一套 inotify 事件。
四、watch 数量上限
监控大量文件(大仓库、node_modules)常见报错:
bash
Failed to watch ... upper limit on inotify watches reachedbash
cat /proc/sys/fs/inotify/max_user_watches # 默认常为 8192/65536
sudo sysctl fs.inotify.max_user_watches=524288 # 临时调大
# /etc/sysctl.d/ 持久化每个被监控目录/文件占一个 watch(不是每事件),递归大目录消耗大,尽量只监控必要目录。相关还有 max_user_instances。
五、和轮询/tail 的区别
- 比定时
ls/find轮询省资源、延迟低(内核事件推送)。 tail -F适合追读一个增长的日志文件内容;inotifywait 适合"发生了什么类型的变化就触发动作",不负责给你内容。- NFS/部分网络文件系统上 inotify 不保证事件,跨机需别的机制。
相关命令
追日志用 tail,定时触发用 crontab,配合 reload 服务用 systemctl,内核实时事件还可用 eBPF/fanotify。
总结
inotifywait = 基于内核 inotify 的事件驱动文件监控:-m -r -e 持续递归地只看 create/modify/delete/close_write 等事件,--format 控输出,典型用于"配置 close_write 后自动 reload";要注意编辑器走临时文件 rename、一次保存多次 modify,监听目录+close_write 更稳;监控海量文件需调大 fs.inotify.max_user_watches,相比轮询省资源、比 tail 更偏"变化触发"而非追读内容。