Linux|inotifywait 异步文件系统监控机制

目录

异步文件系统监控机制 ,可以用来监听文件夹、文件的属性或内容变更的事件。

Inotify 一种强大的、细粒度的、异步文件系统监控机制,它满足各种各样的文件监控需要,可以监控文件系统的访问属性、读写属性、权限属性、删除创建、移动等操作,也就是可以监控文件发生的一切变化。

inotify-tools 是一个 C 库和一组命令行的工作提供 Linux 下 inotify 的简单接口。inotify-tools 安装后会得到 inotifywaitinotifywatch 这两条命令:

  • inotifywait 命令 可以用来收集有关文件访问信息,Linux 发行版一般没有包括这个命令,需要安装 inotify-tools,这个命令还需要将 inotify 支持编译入 Linux 内核,好在大多数 Linux 发行版都在内核中启用了 inotify。
  • inotifywatch 命令 用于收集关于被监视的文件系统的统计数据,包括每个 inotify 事件发生多少次。

开始之前需要检测系统内核是否支持 inotify:

使用 uname -r 命令检查 Linux 内核,如果低于 2.6.13,就需要重新编译内核加入 inotify 的支持。

使用 ll /proc/sys/fs/inotify 命令,是否有以下三条信息输出,如果没有表示不支持。

ll /proc/sys/fs/inotify
total 0
-rw-r--r-- 1 root root 0 Jan  4 15:41 max_queued_events
-rw-r--r-- 1 root root 0 Jan  4 15:41 max_user_instances
-rw-r--r-- 1 root root 0 Jan  4 15:41 max_user_watches

安装 inotify-tools

方式一:

  • inotify-tools 项目地址:https://github.com/rvoicilas/inotify-tools
  • inotify-tools 下载地址:http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
#CentOS release 5.8/64位:
tar zxvf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure
make
make install

其他 Linux 发行版安装方法可以参见:https://github.com/rvoicilas/inotify-tools/wiki#wiki-getting

方式二:使用 yum 工具安装

yum install -y inotify-tools

inotify 相关参数

inotify 定义了下列的接口参数,可以用来限制 inotify 消耗 kernel memory 的大小。由于这些参数都是内存参数,因此,可以根据应用需求,实时的调节其大小:

  • /proc/sys/fs/inotify/max_queued_evnets 表示调用 inotify_init 时分配给 inotify instance 中可排队的 event 的数目的最大值,超出这个值的事件被丢弃,但会触发 IN_Q_OVERFLOW 事件。
  • /proc/sys/fs/inotify/max_user_instances 表示每一个 real user id 可创建的 inotify instatnces 的数量上限。
  • /proc/sys/fs/inotify/max_user_watches 表示每个 inotify instatnces 可监控的最大目录数量。如果监控的文件数目巨大,需要根据情况,适当增加此值的大小。

根据以上在 32 位或者 64 位系统都可以执行:

echo 104857600 > /proc/sys/fs/inotify/max_user_watches
echo 'echo 104857600 > /proc/sys/fs/inotify/max_user_watches' >> /etc/rc.local

如果遇到以下错误:

inotifywait: error while loading shared libraries: libinotifytools.so.0: cannot open shared object file: No such file or directory
 **解决方法:**
32位系统:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib/libinotifytools.so.0
64位系统:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib64/libinotifytools.so.0

inotifywait 命令使用

#!/bin/bash
#filename watchdir.sh
path=$1
/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y/%H:%M' --format '%T %w %f' -e modify,delete,create,attrib $path

执行输出:
./watchdir.sh /data/wsdata/tools/
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swx
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swx
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:34 /data/wsdata/tools/ .j.jsp.swp
04/01/13/16:35 /data/wsdata/tools/ 4913
04/01/13/16:35 /data/wsdata/tools/ 4913
04/01/13/16:35 /data/wsdata/tools/ 4913
04/01/13/16:35 /data/wsdata/tools/ j.jsp
04/01/13/16:35 /data/wsdata/tools/ j.jsp
04/01/13/16:35 /data/wsdata/tools/ j.jsp
04/01/13/16:35 /data/wsdata/tools/ j.jsp~
04/01/13/16:35 /data/wsdata/tools/ .j.jsp.swp

inotifywait 命令参数

  • -m 是要持续监视变化。
  • -r 使用递归形式监视目录。
  • -q 减少冗余信息,只打印出需要的信息。
  • -e 指定要监视的事件列表。
  • --timefmt 是指定时间的输出格式。
  • --format 指定文件变化的详细信息。

可监听的事件

事件 描述
access 访问 ,读取文件。
modify 修改 ,文件内容被修改。
attrib 属性 ,文件元数据被修改。
move 移动 ,对文件进行移动操作。
create 创建 ,生成新文件
open 打开 ,对文件进行打开操作。
close 关闭 ,对文件进行关闭操作。
delete 删除 ,文件被删除。

可以通过 inotifywait --help 查看详细事件。

案例

我们知道 nginx 能够缓存网站静态资源,当我们重新部署网站后,静态资源就被更新了,此时需要让 nginx 重新 reload 一下。这种场景就可以用到 inotifywait 命令,监听网站静态资源文件夹的变化,然后重新 reload nginx。

注意:当监听文件夹时,内部的文件变化会触发事件,并且对同一个文件重新写入会触发多个事件,但要保证 nginx 不能过多 reload。

#!/bin/sh
# 监听博客变更,然后重新加载nginx配置

inotifywait -mq -e create "/data/blog/" | grep -c "/data/blog/ ATTRIB,ISDIR" | while read ret ; do
    if [[ ret > 0 ]]; then
    	nginx -s reload
        echo "nginx 重新加载配置"
    fi
done