本文转自http://www.jiangmiao.org/blog/2179.html
在日常应用中,常常会遇到以下场景,监控文件夹A,若文件夹中的B文件发生变化,则执行C命令。Linux下可以通过inotify完成该功能。
自从Linux kernel 2.6.13起,inotify以作为内核的一部份,同时需要glibc 2.4以上版本。
1. 相关函数
inotify_init() - 创建一个inotify实例
inotify_add_watch(int fd, const char *pathname, uint32_t mask) - 加入文件或目录到inotify进行监测
inotify_rm_watch(int fd, int wd) - 移除一个watcher
2. 相关结构
struct inotify_event { int wd; /* Watch descriptor */ uint32_t mask; /* Mask of events */ uint32_t cookie; /* Unique cookie associating related events (for rename(2)) */ uint32_t len; /* Size of name field */ char name[]; /* Optional null-terminated name */ };
3. Mask
适用于 inotify_add_watch mask 与 read 返回的inotify_event中mask
IN_ACCESS | 文件被访问 |
IN_ATTRIB | 文件属性发生变化 |
IN_CLOSE_WRITE | 以write方式打开文件并关闭 |
IN_CLOSE_NOWRITE | 以非write方式打开文件并关闭 |
IN_CREATE | 文件或目录被创建 |
IN_DELETE | 文件或目录被删除(被监测的文件夹A中B文件被删除) |
IN_DELETE_SELF | 被监测的文件或目录被删除(被监测的文件夹A被删除) |
IN_MODIFY | 文件被修改 |
IN_MOVE_SELF | 被监测的文件或目录移动 |
IN_MOVED_FROM | 文件移出被监测的目录 |
IN_MOVED_TO | 文件移入被监测的目录 |
IN_OPEN | 文件被打开 |
上述flag的集合 | |
IN_ALL_EVENTS | 以上所有flag的集合 |
IN_MOVE | IN_MOVED_TO|IN_MOVED_FROM |
IN_CLOSE | IN_CLOSE_WRITE|IN_CLOSE_NOWRITE |
不常用的flag | |
IN_DONT_FOLLOW | 不follow符号链接 (since 2.6.15) |
IN_EXCL_UNLINK | 当文件从监测目中unlink后,则不再报告该文件的相关event,比如监控/tmp使用 (since 2.6.36) |
IN_MASK_ADD | 追打MASK到被监测的pathname |
IN_ONESHOT | 只监测一次 |
IN_ONLYDIR | 只监测目录 |
仅由read返回
IN_IGNORED | inotify_rm_watch,文件被删除或者文件系统被umount |
IN_ISDIR | 发生事件的是一个目录 |
IN_Q_OVERFLOW | Event队列溢出 |
IN_UNMOUNT | 文件系统unmount |
4. 例子
用途:监测指定文件或目录(或不指定则为当前目录)的一切动作。
使用:inotify [文件或目录]
#include <unistd.h> #include <sys/inotify.h> #include <stdio.h> #include <error.h> #include <errno.h> #include <string.h> #define ERROR(text) error(1, errno, "%s", text) struct EventMask { int flag; const char *name; }; int freadsome(void *dest, size_t remain, FILE *file) { char *offset = (char*)dest; while (remain) { int n = fread(offset, 1, remain, file); if (n==0) { return -1; } remain -= n; offset += n; } return 0; } int main(int argc, char *argv[]) { const char *target; if (argc == 1) { target = "."; } else { target = argv[1]; } EventMask event_masks[] = { {IN_ACCESS , "IN_ACCESS"} , {IN_ATTRIB , "IN_ATTRIB"} , {IN_CLOSE_WRITE , "IN_CLOSE_WRITE"} , {IN_CLOSE_NOWRITE , "IN_CLOSE_NOWRITE"} , {IN_CREATE , "IN_CREATE"} , {IN_DELETE , "IN_DELETE"} , {IN_DELETE_SELF , "IN_DELETE_SELF"} , {IN_MODIFY , "IN_MODIFY"} , {IN_MOVE_SELF , "IN_MOVE_SELF"} , {IN_MOVED_FROM , "IN_MOVED_FROM"} , {IN_MOVED_TO , "IN_MOVED_TO"} , {IN_OPEN , "IN_OPEN"} , {IN_DONT_FOLLOW , "IN_DONT_FOLLOW"} , {IN_EXCL_UNLINK , "IN_EXCL_UNLINK"} , {IN_MASK_ADD , "IN_MASK_ADD"} , {IN_ONESHOT , "IN_ONESHOT"} , {IN_ONLYDIR , "IN_ONLYDIR"} , {IN_IGNORED , "IN_IGNORED"} , {IN_ISDIR , "IN_ISDIR"} , {IN_Q_OVERFLOW , "IN_Q_OVERFLOW"} , {IN_UNMOUNT , "IN_UNMOUNT"} , }; int monitor = inotify_init(); if ( -1 == monitor ) { ERROR("monitor"); } int watcher = inotify_add_watch(monitor, target, IN_ALL_EVENTS); if ( -1 == watcher ) { ERROR("inotify_add_watch"); } FILE *monitor_file = fdopen(monitor, "r"); char last_name[1024]; char name[1024]; /* event:inotify_event -> name:char[event.len] */ while (true) { inotify_event event; if ( -1 == freadsome(&event, sizeof(event), monitor_file) ) { ERROR("freadsome"); } if (event.len) { freadsome(name, event.len, monitor_file); } else { sprintf(name, "FD: %d\n", event.wd); } if (strcmp(name, last_name) != 0) { puts(name); strcpy(last_name, name); } /* 显示event的mask的含义 */ for (int i=0; i<sizeof(event_masks)/sizeof(EventMask); ++i) { if (event.mask & event_masks[i].flag) { printf("\t%s\n", event_masks[i].name); } } } return 0; }
运行结果: vim 中 对监测目录中的 inotify.cc 进行保存
4913 IN_CREATE IN_OPEN IN_ATTRIB IN_CLOSE_WRITE IN_DELETE inotify.cc IN_MOVED_FROM inotify.cc~ IN_MOVED_TO inotify.cc IN_CREATE IN_OPEN IN_MODIFY IN_CLOSE_WRITE IN_ATTRIB inotify.cc~ IN_DELETE
可以看到,vim保存文件的流程为
创建一个4913文件用于检测vim对目录的控制权限
把inotify.cc更名为inotify.cc~
新建inotify.cc,并写入buffer
删除inotify.cc
Linux 下文件监控的更多相关文章
-
Windows与Linux下文件操作监控的实现
一.需求分析: 随着渲染业务的不断进行,数据传输渐渐成为影响业务时间最大的因素.究其原因就是因为数据传输耗费较长的时间.于是,依托于渲染业务的网盘开发逐渐成为迫切需要解决的需求.该网盘的实现和当前市场 ...
-
[转帖]Linux下inotify监控文件夹状态,发生变化后触发rsync同步
Linux下inotify监控文件夹状态,发生变化后触发rsync同步 https://www.cnblogs.com/fjping0606/p/6114123.html 1.安装工具--inotif ...
-
Linux下文件的三种时间戳
Linux下文件的三种时间标记 三种时间对应关系表 column column column 访问时间 Access atime 修改时间 Modify mtime 状态改动时间 Change cti ...
-
linux下文件结束符
linux下文件结束符,我试过了所有的linux,发现其文件的结束符都是以0a即LF结束的,这个是操作系统规定的,windows下是\r\n符结束,希望可以帮助大家. -------------转:来 ...
-
dos2unix,去掉Linux下文件中的^M
Windows系统下使用VS2010编写好的CPP文件,想放到Linux上进行编译.发现Linux上文件中的每行代码末尾都跟着^M这个符号. 为什么同一份文件在windows上和Linux上显示的不一 ...
-
linux下文件的复制、移动与删除
linux下文件的复制.移动与删除命令为:cp,mv,rm 一.文件复制命令cp 命令格式:cp [-adfilprsu] 源文件(source) 目标文件(destination) ...
-
Linux下文件的权限
一.Linux下查看文件属性 命令为: [root@localhost ~]# ls -al 结果: ls是『list』的意思,重点在显示文件的文件名与相关属性.而选项『-al』则表示列出所有的文件详 ...
-
LINUX下文件编译
body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...
-
linux 下文件误删恢复
linux 下文件误删恢复 0x01 事件背景 某天晚上写代码的时候,本来想删除当前目录下一个叫xxx的文件夹 rm -rdf ./xxx/*, 结果光顾着和人说话,一不留神手贱把命令敲成了rm -r ...
随机推荐
-
css计数器详解
什么是css计数器 体验更佳排版请戳原文链接:http://blog.liuxianan.com/css-counters.html 就是采用css给一些html元素自动生成编号,比如类似1.3.2这 ...
-
DDD~我们应该知道的Model,DomainModel和ViewModel
回到目录 图在前 目前项目中可能出现的三种Model模式,对于我们现在开发的一个项目,我觉得使用DDD的思想来设计模型比较清晰,使用DDD的思想把模型model分成了如下三种: 下面是我微博中的截 ...
-
简单的C#线程开发实例(隔一秒改变一下Label的Text)
要实现的效果:点击按纽,窗口上的label上出现1~100数字的变化. 第一个实例(把窗口上的label上文字改成0): using System; using System.Windows.Form ...
-
利用red5搭建一个简单的流媒体直播系统
http://blog.sina.com.cn/s/blog_51396f890102exmz.html 一.red5安装.设置. 这个过程就不多说了,参见http://blog.csdn.net/l ...
-
FG面经: Interval问题合集
How to insert interval to an interval list. List is not sorted O(N) solution: package fb; import jav ...
-
Qt带返回值的信号发射方式(使用QMetaObject::invokeMethod)
一般来说,我们发出信号使用emit这个关键字来操作,但是会发现,emit并不算一个调用,所以它没有返回值.那么如果我们发出这个信号想获取一个返回值怎么办呢? 两个办法:1.通过出参形式返回,引用或者指 ...
-
vuex状态管理-数据改变不刷新
困惑: 在页面初始化的时候,我提交到vuex状态管理,然后在获取的时候获取不到,我找到了出错的地点,并进行了修改,然后可以获取到状态 但是不知道原因? 定义了如下的state const state ...
-
0001——初涉MySQL
MySQL是一个开源的关系型数据库管理系统. MySQL分为社区版本和企业版 MySQL安装方式: 1.MSI安装(Windows Installer) 2.ZIP安装 选择安装类型: 1.T ...
-
Netty学习第三节Netty的入门级学习
1.原生NIO存在哪些缺陷 (1)NIO的类库和API繁杂,使用也比较麻烦,需要熟练掌握selector.ServerSocketChannel.SocketChannel.ByteBuffe ...
-
Eclipse批量替换
情景: 我需要将项目中所有有"上样板"的字样替换为"PCR板",如果寻找单个页面肯定是很麻烦,而且替换很有可能不全,那么该怎么才能完全替换呢? 解决方法: ec ...