目录
1.inotify简介
- Inotify是一种强大的,细粒度的,异步的文件系统事件监控机制(软件),linux内核从2.6.13起,加入了Inotify支持,通过Inotify可以监控文件系统中添加,删除,修改,移动等各种事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况。
- Inotify实际是一种事件驱动机制,它为应用程序监控文件系统事件提供了实时响应事件的机制,而无须通过诸如cron等的轮询机制来获取事件。cron等机制不仅无法做到实时性,而且消耗大量系统资源。相比之下,inotify基于事件驱动,可以做到对事件处理的实时响应,也没有轮询造成的系统资源消耗,是非常自然的事件通知接口,也与自然世界的事件机制相符合。
- inotify 的实现有几款软件
1)inotify-tools
2)sersync(金山周洋)
3)lsyncd
2. inotify-tools安装
2.1 是否支持inotify
[root@study ~]# uname -r
3.10.0-862.el7.x86_64
[root@study ~]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Sep 24 03:33 max_queued_events
-rw-r--r-- 1 root root 0 Sep 24 03:33 max_user_instances
-rw-r--r-- 1 root root 0 Sep 24 03:33 max_user_watches
注:显示以上文件为支持
参数说明:
max_queued_events #设置inotify实例事件(event)队列可容纳的事件数量。
max_user_instances #设置每个用户可以运行的inotifywait或inotifywatch命令的进程数。
max_user_watches #设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)
2.2 安装inotify-tools
rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
yum install -y inotify-tools
inotify-tools提供了两个命令行工具:
[root@study ~]# rpm -ql inotify-tools | grep /bin
/usr/bin/inotifywait
/usr/bin/inotifywatch
inotifywait:在被监控的文件或目录上等待特定文件系统事件(open,close,delete等)发生,执行后处于阻塞状态,适合shell脚本中使用。
inotifywatch:用于收集文件系统的统计数据,例如发生了多少次inotify事件,某文件被访问了多少次等等,一般用不上。
2.3 inotifywait命令解析及事件分析
inotifywait 参数:
-m:--monitor表示始终监控,否则应该是监控到了一次就退出监控了
-r:--recursive 递归监控,监控目录中的任何文件,包括子目录。递归监控可能会超出max_user_watches的值,需要适当调整该值
-q:--quiet 的意思,静默监控,这样就不会输出一些无关的信息
-e:指定监控的事件。一般监控的就delete、create、attrib、modify、close_write,若未指定就监控所有事件。
@<file>:如果是对目录进行递归监控,则该选项用于排除递归目录中不被监控的文件。file是相对路径还是绝对路径由监控目录是相对还是绝对来决定
--exclude <pattern> :通过模式匹配来指定不被监控的文件,区分大小写
--excludei <pattern>:通过模式匹配来指定不被监控的文件,不区分大小写
--timefmt:监控到事件触发后,输出的时间格式,可指定可不指定该选项,一般设置为[--timefmt '%Y/%m/%d %H:%M:%S']
--format :用户自定义的输出格式,如[--format '%w%f %e%T']
%w:产生事件的监控路径,不一定就是发生事件的具体文件,例如递归监控一个目录,该目录下的某文件产生事件,将输出该目录而非其内具体的文件
%f:如果监控的是一个目录,则输出产生事件的具体文件名。其他所有情况都输出空字符串
%e:产生的事件名称
%T:以"--timefmt"定义的时间格式输出当前时间,要求同时定义"--timefmt"
inotifywait -e事件:
access :文件被访问
modify :文件被写入
attrib :元数据被修改。包括权限、时间戳、扩展属性等等
close_write :打开的文件被关闭,是为了写文件而打开文件,之后被关闭的事件
close_nowrite:read only模式下文件被关闭,即只能是为了读取而打开文件,读取结束后关闭文件的事件
close :是close_write和close_nowrite的结合,无论是何种方式打开文件,只要关闭都属于该事件
open :文件被打开
moved_to :向监控目录下移入了文件或目录,也可以是监控目录内部的移动
moved_from :将监控目录下文件或目录移动到其他地方,也可以是在监控目录内部的移动
move :是moved_to和moved_from的结合
moved_self :被监控的文件或目录发生了移动,移动结束后将不再监控此文件或目录
create :在被监控的目录中创建了文件或目录
delete :删除了被监控目录中的某文件或目录
delete_self :被监控的文件或目录被删除,删除之后不再监控此文件或目录
umount :挂载在被监控目录上的文件系统被umount,umount后不再监控此目录
isdir :监控目录相关操作
inotifywait事件分析:
mkdir /work
inotifywait -m /work
(1) 向目录中创建文件、目录,触发create、open 、attrib、close_write、close、isdir事件。
[root@study ~]# touch /work/test.txt
/work/ CREATE test.txt
/work/ OPEN test.txt
/work/ ATTRIB test.txt
/work/ CLOSE_WRITE,CLOSE test.txt
[root@study~]# mkdir /work/test
/work/ CREATE,ISDIR test
(2) 修改文件属性,触发attrib事件。
[root@study ~]# chmod 666 /work/
/work/ ATTRIB,ISDIR
(3) cat查看文件,触发open、access、close_nowrite和close事件。
[root@study ~]# cat /work/test.txt
/work/ OPEN test.txt
/work/ ACCESS test.txt
/work/ CLOSE_NOWRITE,CLOSE test.txt
注:test.txt必须要有内容才会触发access事件
(4) 向文件中追加或写入或清除数据,触发open、modify、close_write和close事件。
[root@study ~]# echo "hello" >> /work/test.txt
/work/ OPEN test.txt
/work/ MODIFY test.txt
/work/ CLOSE_WRITE,CLOSE test.txt
(5) vim打开文件并修改文件,中间涉及到临时文件,所以有非常多的事件。
/work/ OPEN test.txt
/work/ CREATE .test.txt.swp
/work/ OPEN .test.txt.swp
/work/ CREATE .test.txt.swx
/work/ OPEN .test.txt.swx
/work/ CLOSE_WRITE,CLOSE .test.txt.swx
/work/ DELETE .test.txt.swx
/work/ CLOSE_WRITE,CLOSE .test.txt.swp
/work/ DELETE .test.txt.swp
/work/ CREATE .test.txt.swp
....
注:其中有"ISDIR"标识的是目录事件。此外,需要注意到vim过程中,相应的几个临时文件(.swp、.swx和以~为后缀的备份文件)也产生了事件,这些临时文件的相关事件在实际应用过程中,其实不应该被监控。
(6) 向目录中拷入一个文件,触发create、open、modify和close_write、close事件。其实和新建文件基本类似。
[root@study ~]# cp /etc/fstab /work/
/work/ CREATE fstab
/work/ OPEN fstab
/work/ MODIFY fstab
/work/ CLOSE_WRITE,CLOSE fstab
(7) 向目录中移入和移除一个文件。
[root@study ~]# mv /etc/passwd /work/
/work/ MOVED_TO passwd
(8) 删除一个文件,触发delete事件。
[root@study ~]# rm -f /work/test.txt
/work/ DELETE test.txt
总结:由于一般情况下,inotify都是监控文件的增删改,而对查看文件不做监控,所有通过上面的测试,可以初步得出一般监控close_write、move、delete、isdir等事件。
2.4 inotifywatch命令解析
虽然这个命令用的不多,但本文还是对其做一个简单分析。
inotifywatch参数:
-h -–help # 输出帮助信息
-v -–verbose # 输出详细信息
@<file> # 排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
-–fromfile <file> # 从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-z -–zero # 输出表格的行和列,即使元素为空
-–exclude # 正则匹配需要排除的文件,大小写敏感。
-–excludei # 正则匹配需要排除的文件,忽略大小写。
-r -–recursive # 监视一个目录下的所有子目录。
-t –-timeout # 设置超时时间
-e –-event # 只监听指定的事件。 监听事件同上
-a –-ascending # 以指定事件升序排列。
-d -–descending # 以指定事件降序排列
eg:统计/work/目录发生事件的次数
在/wrok目录下,创建了4个文件,修改了3个文件内容,删除了一个文件。
inotifywatch -v -e create,modify,delete -t 30 -r /work
[root@study ~]# touch /work/test{1..4}
[root@study ~]# echo "test1" >> /work/test1
[root@study ~]# echo "test2" >> /work/test2
[root@study ~]# echo "test3" >> /work/test3
[root@study ~]# rm -f /work/test4
Will listen for events for 60 seconds.
total modify create delete filename
8 3 4 1 /work/
2.5 简单应用
监控/work 目录下发生的 delete,attrib,close_write,moved_to,moved_from,isdir等事件。
#!/bin/bash
inotifywait -mrq --timefmt '%Y/%m/%d %H:%M' --format '%T %w%f %e' --event delete,attrib,close_write,moved_to,moved_from,isdir /work |\
while read line
do
if echo $line | grep -i -E "ATTRIB|CLOSE_WRITE|DELETE|MOVED_TO|MOVED_FROM|ISDIR";then
echo $line >> /tmp/inotify.log
fi
done
2.6 inotify系统参数修改
[root@study inotify]# cd /proc/sys/fs/inotify/
[root@study inotify]# ll
total 0
-rw-r--r-- 1 root root 0 Sep 24 16:51 max_queued_events
-rw-r--r-- 1 root root 0 Sep 24 16:51 max_user_instances
-rw-r--r-- 1 root root 0 Sep 24 16:51 max_user_watches
[root@study inotify]# cat *
16384
128
8192
注:直接使用vim进行修改会报错,修改不成功。
法一:
echo "16385" >> max_queued_events
echo "129" >> max_user_instances
echo "8193" >> max_user_watches
法二:
sysctl -w fs.inotify.max_queued_events="16385"
sysctl -w fs.inotify.max_user_instances="129"
sysctl -w fs.inotify.max_user_watches="8193"
以上两种方法本人亲测有效。