文档章节

使用 inotify 监控文件与目录

行者深蓝
 行者深蓝
发布于 2013/01/06 15:52
字数 1956
阅读 877
收藏 0

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

inotify 介绍
从文件管理器到安全工具,文件系统监控对于的许多程序来说都是必不可少的。从 Linux 2.6.13 内核开始,Linux 就推出了 inotify,允许监控程序打开一个独立文件描述符,并针对事件集监控一个或者多个文件,例如打开、关闭、移动/重命名、删除、创建或者改变属性。在后期的内核中有了很多增强,因此在依赖这些特性之前,请先检查您的内核版本。
在本文中,您将会学习如何在简单的监控应用程序中使用 inotify 功能。下载样例代码,在您的系统上编译,进一步探索。
回页首
历史简介
在 inotify 之前有 dnotify。不幸的是,dnotify 有局限性,用户需要更好的产品。和 dnotify 相比 inotify 的优势如下:
Inotify 使用一个独立的文件描述符,而 dnotify 需要为每个受监控的目录打开一个文件描述符。当您同时监控多个目录时成本会非常高,而且还会遇到每进程文件描述符限制。
Inotify 所使用的文件描述符可以通过系统调用获得,并且没有相关设备或者文件。而使用 dnotify,文件描述符就固定了目录,妨碍备用设备卸载,这是可移动媒体的一个典型问题。对于 inotify,卸载的文件系统上的监视文件或目录会产生一个事件,而且监视也会自动移除。
Inotify 能够监视文件或者目录。Dnotify 则只监视目录,因此程序员还必须保持 stat 结构或者一个等效的数据结构,来反映该被监视目录中的文件,然后在一个事件发生时,将其与当前状态进行对比,以此了解当前目录中的条目发生了什么情况。
如上所述,inotify 使用文件描述符,允许程序员使用标准 select 或者 poll 函数来监视事件。这允许高效的多路复用 I/O 或者与 Glib 的 mainloop 的集成。相比之下,dnotify 使用信号,这使得程序员觉得比较困难或者不够流畅。在 2.6.25 内核中 inotify 还添加了 Signal-drive I.O 通知功能。
回页首
用于 inotify 的 API
Inotify 提供一个简单的 API,使用最小的文件描述符,并且允许细粒度监控。与 inotify 的通信是通过系统调用实现。可用的函数如下所示:
inotify_init
是用于创建一个 inotify 实例的系统调用,并返回一个指向该实例的文件描述符。
inotify_init1
与 inotify_init 相似,并带有附加标志。如果这些附加标志没有指定,将采用与 inotify_init 相同的值。
inotify_add_watch
增加对文件或者目录的监控,并指定需要监控哪些事件。标志用于控制是否将事件添加到已有的监控中,是否只有路径代表一个目录才进行监控,是否要追踪符号链接,是否进行一次性监控,当首次事件出现后就停止监控。
inotify_rm_watch
从监控列表中移出监控项目。
read
读取包含一个或者多个事件信息的缓存。
close
关闭文件描述符,并且移除所有在该描述符上的所有监控。当关于某实例的所有文件描述符都关闭时,资源和下层对象都将释放,以供内核再次使用。
因此,典型的监控程序需要进行如下操作:
使用 inotify_init 打开一个文件描述符
添加一个或者多个监控
等待事件
处理事件,然后返回并等待更多事件
当监控不再活动时,或者接到某个信号之后,关闭文件描述符,清空,然后退出。
在下一部分中,您将看到可以监控的事件,它们如何在简单的程序中运行。最后,您将看到事件监控如何进行。
回页首
通告
当您的应用程序读取到一个通告时,事件的顺序也被读取到您提供的缓存中。事件在一个变长结构中被返回,如清单 1 所示。如果数据占满了您的缓存,您可能需要对最后一个条目进行局部事件信息或者局部名处理。


清单 1. 用于 inotify 的事件结构体

struct inotify_event
{
  int wd;                   /* Watch descriptor.  */
  uint32_t mask;        /* Watch mask.  */
  uint32_t cookie;      /* Cookie to synchronize two events.  */
  uint32_t len;           /* Length (including NULs) of name.  */
  char name __flexarr;  /* Name.  */
  };


请注意,只有当监控对象是一个目录并且事件与目录内部相关项目有关,而与目录本身无关时,才提供 name 字段。如果 IN_MOVED_FROM 事件与相应的 IN_MOVED_TO 事件都与被监控的项目有关,cookie 就可用于将两者关联起来。事件类型在掩码字段中返回,并伴随着能够被内核设置的标志。例如,如果事件与目录有关,则标志 IN_ISDIR 将由内核设置。
回页首
可监控的事件
有几种事件能够被监控。一些事件,比如 IN_DELETE_SELF 只适用于正在被监控的项目,而另一些,比如 IN_ATTRIB 或者 IN_OPEN 则只适用于监控过的项目,或者如果该项目是目录,则可以应用到其所包含的目录或文件。
IN_ACCESS
被监控项目或者被监控目录中的条目被访问过。例如,一个打开的文件被读取。
IN_MODIFY
被监控项目或者被监控目录中的条目被修改过。例如,一个打开的文件被修改。
IN_ATTRIB
被监控项目或者被监控目录中条目的元数据被修改过。例如,时间戳或者许可被修改。
IN_CLOSE_WRITE
一个打开的,等待写入的文件或目录被关闭。
IN_CLOSE_NOWRITE
一个以只读方式打开的文件或目录被关闭。
IN_CLOSE
一个掩码,可以很便捷地对前面提到的两个关闭事件(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)进行逻辑操作。
IN_OPEN
文件或目录被打开。
IN_MOVED_FROM
被监控项目或者被监控目录中的条目被移出监控区域。该事件还包含一个 cookie 来实现 IN_MOVED_FROM 与 IN_MOVED_TO 的关联。
IN_MOVED_TO
文件或目录被移入监控区域。该事件包含一个针对 IN_MOVED_FROM 的 cookie。如果文件或目录只是被重命名,将能看到这两个事件,如果它只是被移入或移出非监控区域,将只能看到一个事件。如果移动或重命名一个被监控项目,监控将继续进行。参见下面的 IN_MOVE-SELF。
IN_MOVE
可以很便捷地对前面提到的两个移动事件(IN_MOVED_FROM | IN_MOVED_TO)进行逻辑操作的掩码。
IN_CREATE
在被监控目录中创建了子目录或文件。
IN_DELETE
被监控目录中有子目录或文件被删除。
IN_DELETE_SELF
被监控项目本身被删除。监控终止,并且将收到一个 IN_IGNORED 事件。
IN_MOVE_SELF
监控项目本身被移动。
除了事件标志以外,还可以在 inotify 头文件(/usr/include/sys/inotify.h)中找到其他几个标志。例如,如果只想监控第一个事件,可以在增加监控时设置 IN_ONESHOT 标志。

#include<stdio.h>
#include<unistd.h>
#include<sys/inotify.h>

#define MAX_EVENTS 256
#define BUFFER_SIZE (MAX_EVENTS * sizeof(struct inotify_event))

int main(int argc , char *argv[])
{
	int i=0;
	int len;
	int inotify_fd;
	int inotify_wd;
	int inotify_err;
	struct inotify_event *ievent;
	
	if( argc != 2 )
		{
		printf("no input !");	
		return -1;
		}
	
	inotify_fd = inotify_init();
	if ( inotify_fd < 0 )
		printf("can't init inotify ");
	
	inotify_wd=inotify_add_watch(inotify_fd, argv[1] , IN_CREATE );
	
	while(1)
	{
		i=0;
		char ev_buffer[BUFFER_SIZE];
		len= read(inotify_fd, ev_buffer,BUFFER_SIZE);
		while(i<len)
		{
			
         		ievent=(struct inotify_event *)&ev_buffer[i];
			if (ievent->len) printf("[%s]",ievent->name);
			if(ievent->mask & IN_CREATE ) printf("create");
		}
       }
}

 

本文转载自网络

行者深蓝
粉丝 33
博文 60
码字总数 44225
作品 0
朝阳
程序员
私信 提问
加载中

评论(0)

php使用inotify扩展监控文件或目录的变化

一、安装inotify扩展 1、下载inotify扩展源码 https://pecl.php.net/package/inotify 对于php7以上版本,请下载 inotify-2.0.0.tgz。 2、编译安装 tar xf inotify-2.0.0.tgzcd inotify-2.0.0......

osc_jtynr6ek
2019/05/14
3
0
inotify机制监控文件系统事件原理及使用

基本描述 inotify提供了一种监控文件系统事件的机制,可以用来监控单个的文件以及目录。当一个目录被监控,inotify会返回该目录以及该目录下面文件的事件。 2. 原理以及使用 2.1 内核原理 in...

osc_7v0r6mp8
2018/07/12
9
0
全网实时热备inotify+rsync

title: 全网实时热备inotify+rsync tags: 备份,inotify,rsync 全网实时热备inotify+rsync 1 为什么需要inotify? 当全网部署了NFS存储后,如果提供NFS服务的设备宕机或者故障了,那么我们的与...

chacha51
2018/05/29
0
0
swoole+inotify实现异步实时文件监控

inotify扩展介绍 inotify是Linux内核提供的一组系统调用,它可以监控文件系统操作,比如文件或者目录的创建、读取、写入、权限修改和删除等。 inotify使用也很简单,使用inotifyinit创建一个...

matyhtf
2014/11/12
7.1K
3
inotify-tools工具安装配置

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

SA_小科
2018/05/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

websocket实现一个聊天室

上次讲了websoket的基础知识和应用插件,今天我们来用websocket来实现一个聊天程序。先看几张界面截图: 聊天界面: 历史消息查看: 用户上线提醒: 在线体验地址:地址 功能结构图 可以看到...

osc_k1o54uky
23分钟前
25
0
gvim的基本配置(中文乱码,行号和主题)

在C:\Program Files\Vim目录下的 _vimrc文件中,插入基本配置,包括中文乱码,行号和主题。 " Vim with all enhancementssource $VIMRUNTIME/vimrc_example.vim" 解决中文乱码set encodi......

osc_jcfo5qp3
24分钟前
15
0
cad版本转换器哪一款好用?DWG和DXF文件如何互转?

很多工作者在工作时发现,有时候自己接收到一个文件,点击打开时发现打不开,显示文件格式不对,遇见这样的情况就需要把文档转换成自己常用的文件格式。只有经过转换过的图才能打开查看,那么...

真不莲
25分钟前
20
0
C++类中引用成员和常量成员的初始化(初始化列表)

如果一个类是这样定义的: Class A{ public: A(int pram1, int pram2, int pram3); privite: int a; int &b; const int c; } ......

osc_y9y4gqxx
25分钟前
23
0
三年OI——我的初中信竞生涯

目录 前言 Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 后记 前言 OI至今已三年,小记一则,兼怀往事 文采不加,文章不伦不类,愧对语文老师 Part 1 初一上学期时,家父听说\(xzy\)(学长)得...

osc_9fexqrfv
26分钟前
24
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部