1、简介shell
Inotify 是一个 Linux 内核特性,它监控文件系统,而且及时向专门的应用程序发出相关的事件警告,好比删除、读、写和卸载操做等。您还能够跟踪活动的源头和目标等细节。在实际项目中,若是项目带有配置文件,那么怎么让配置文件的改变和项目程序同步而不须要重启程序呢?一个明显的应用是:在一个程序中,使用Inotify监视它的配置文件,若是该配置文件发生了更改(更新,修改)时,Inotify会产生修改的事件给程序,应用程序就能够实现从新加载配置文件,检测哪些参数发生了变化,并在应用程序内存的一些变量作相应的修改。固然另外一种方法能够是经过cgi注册命令,并经过命令更新内存数据及更新配置文件
cookie
Inotify 能够监视的文件系统事件包括:
IN_ACCESS,即文件被访问
IN_MODIFY,文件被 write
IN_ATTRIB,文件属性被修改,如 chmod、chown、touch 等
IN_CLOSE_WRITE,可写文件被 close
IN_CLOSE_NOWRITE,不可写文件被 close
IN_OPEN,文件被 open
IN_MOVED_FROM,文件被移走,如 mv
IN_MOVED_TO,文件被移来,如 mv、cp
IN_CREATE,建立新文件
IN_DELETE,文件被删除,如 rm
IN_DELETE_SELF,自删除,即一个可执行文件在执行时删除本身
IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动本身
IN_UNMOUNT,宿主文件系统被 umount
IN_CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
IN_MOVE,文件被移动,等同于(IN_MOVED_FROM | IN_MOVED_TO)
注:上面所说的文件也包括目录。
测试
2、使用Inofityflex
要使用 inotify,您必须具有一台带有 2.6.13 或更新内核的 Linux 机器(之前的 Linux 内核版本使用更低级的文件监控器dnotify)。若是您不知道内核的版本,请转到 shell,输入 uname -a
:ui
您还能够检查机器的 /usr/include/sys/inotify.h 文件。若是它存在,代表您的内核支持 inotify。spa
使用 inotify 很简单:建立一个文件描述符,附加一个或多个监视器(一个监视器 是一个路径和一组事件),而后使用 read()
方法从描述符获取事件信息。read()
并不会用光整个周期,它在事件发生以前是被阻塞的。.net
更好的是,由于 inotify 经过传统的文件描述符工做,您能够利用传统的 select()
系统调用来被动地监控监视器和许多其余输入源。两种方法 — 阻塞文件描述符和使用 select()
— 都避免了繁忙轮询。code
Inotify 提供 3 个系统调用,它们能够构建各类各样的文件系统监控器:blog
int fd = inotify_init()
在内核中建立 inotify 子系统的一个实例,成功的话将返回一个文件描述符,失败则返回 -1。就像其余系统调用同样,若是 inotify_init()
失败,请检查 errno
以得到诊断信息。inotify_add_watch(fd,path,mask)
用于添加监视器。每一个监视器必须提供一个路径名和相关事件的列表(每一个事件由一个常量指定,好比 IN_MODIFY)。要监控多个事件,只需在事件之间使用逻辑操做符或 — C 语言中的管道线(|
)操做符。若是 inotify_add_watch()
成功,该调用会为已注册的监视器返回一个唯一的标识符;不然,返回 -1。使用这个标识符更改或删除相关的监视器。int ret = inotify_rm_watch(fd, wd)
删除一个监视器。 此外,还须要 read()
和 close()
系统调用。若是描述符由 inotify_init()
生成,则调用 read()
等待警告。假设有一个典型的文件描述符,应用程序将阻塞对事件的接收,这些事件在流中表现为数据。文件描述符上的由 inotify_init()
生成的通用close()
删除全部活动监视器,并释放与 inotify 实例相关联的全部内存(这里也用到典型的引用计数警告。与实例相关联的全部文件描述符必须在监视器和 inotify 消耗的内存被释放以前关闭)。事件
3、测试Inotify
在文件 /usr/include/sys/inotify.h. 中,您能够找到事件结构的定义,它是一种 C 结构,以下所示:
结构中的char name是不占空间的,至关于char name[0],因此sizeof(struct inotify_event)长度是16,实际上该结构数据的总长度应该是16+len,数据是紧跟在uinit32_t len后面的数据。
测试代码以下:
以上代码须要注意的地方:
1.若是在/tmp目录下touch kill文件,程序则会退出
2.若是只有一个add watch 一个file,那么这个file的更改产生的event事件中event->len是为0,须要额外的处理,此代码省略了具体的处理过程,以注释代替
3.若是监测的是文件或目录的更改,使用 echo "xxx" >> file,会产生一个event事件,而使用echo "xxx" > file 会产生两个event事件,查了相关的资料,多是由于后者须要先清空file文件内容,形成第一次event事件,再将xxx写入file保存,形成了第二次的event事件。