最近写一些shell脚本的时候,需要读取远程服务器的目录下的文件同步到当前服务器的指定目录下,因为使用的是增量同步,所以需要监控文件夹下文件的变化,最终选择使用Inotify用来监控。
Inotify是一种文件变化通知机制,Linux内核从2.6.13开始引入,它可以高效的跟踪Linux文件系统的变化。
一、判断内核支持Inotify
grep "CONFIG_INOTIFY_USER" /boot/config-$(uname -r)
命令执行后如下:
如果输出内容中包含CONFIG_INOTIFY_USER=y说明操作系统支持Inotify
二、安装inotify-tools
下载与解压缩
wget https://nchc.dl.sourceforge.net/project/inotify-tools/inotify-tools/3.13/inotify-tools-3.13.tar.gz
tar zxvf inotify-tools-3.13.tar.gz
配置
cd inotify-tools-3.13
./configure --prefix=/usr/local/inotify-tools-3.13
编译安装
make && make install
配置环境变量
# 删除INOTIFY_TOOLS_HOME配置
sed -i '/INOTIFY_TOOLS_HOME/d' /etc/profile
# 添加INOTIFY_TOOLS_HOME环境变量
echo 'export INOTIFY_TOOLS_HOME=/usr/local/inotify-tools-3.13/' >> /etc/profile
# 添加inotify tools的可执行文件到PATH环境变量
echo 'export PATH=$PATH:$INOTIFY_TOOLS_HOME/bin' >> /etc/profile
# 使环境变量生效
source /etc/profile
三、inotifywait
此命令可以用于监控文件及文件夹,可以使用man inotifywait查看命令的帮助文档
1、监听
下面我们使用inotifywait监控/home文件夹下文件的变化,执行命令:
# m代表的是循环监听,否则监听到后退出
# r代表的是递归监听,否则只监听指定文件夹下的变化
inotifywait -rm /home
执行命令后,会一直处于阻塞状态:
打开另外一个终端,依次在/home/dev目录下完成以下操作:
- 新建一个文件夹(mkdir test)
- 进入test文件夹,创建text.txt文件(cd test && touch text.txt)
- 修改text.txt文件的内容(echo 'hello world'>> text.txt)
- 查看text.txt文件的内容(more text.txt)
- 删除text.txt文件(rm text.txt)
- 进入/home/dev目录,删除test目录(rm -r test)
可以看到监听到的日志如下:
可以看到inotifywait监听到的事件,大体上还是很清晰的。如果想了解inotify提供的事件,可以参考:https://linux.die.net/man/1/inotifywatch
2、排除监听
在某些情况下我们可能不想监听某个文件或文件夹的变化,我们可以使用--exclude排除对指定文件或文件夹的监听。
下面我们使用inotifywait监控/home文件夹下文件的变化,但不监听/home/dev下的变化,执行命令:
# m代表的是循环监听,否则监听到后退出
# r代表的是递归监听,否则只监听指定文件夹下的变化
inotifywait --exclude /home/dev -rm /home
再在/home/dev目录下执行创建文件及文件夹等操作,发现已经监听不到。
另外--exclude后面可以使用正则表达式
四、Inotify配置
内核中有两项关于Inotify的配置:
/proc/sys/fs/inotify/max_user_instances规定了每个用户所能创建的 Inotify 实例的上限(默认是128)
/proc/sys/fs/inotify/max_user_watches规定了每个Inotify实例最多能关联几个监控 (watch)(默认是8192)
1、修改用户Inotify实例上限
下面我们将max_user_instances修改为0:
echo 0 > /proc/sys/fs/inotify/max_user_instances
再使用inotifywait命令进行监听时会失败:
测试结束后将max_user_instances再修改回128
2、修改Inotify关联watch上限
下面我们将max_user_watches修改为0:
echo 0 > /proc/sys/fs/inotify/max_user_watches
再使用inotifywait命令进行监听时会失败:
测试结束后将max_user_watches再修改回8192