Linux 下文件监控
本文转自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 ...
随机推荐
- web03--session
1.创建session1.jsp <body> <form action="session2.jsp" method="post"> & ...
- 汉字转拼音(pinyin4j-2.5.0.jar)
import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuPinyinCase ...
- AJAX校验用户名是否存在,焦点离开用户名、点击 【 检 查用户名 】的校验。分别用 XMLHttp 和 JQueryAJAX实现。
XMLHttp方法: $("#name").blur(function () { var xmlhttp = new ActiveXObject("Microsoft. ...
- ajaxfileupload
} } setTimeout( }, s. ...
- 几种破解MySQL root密码的几种方法:
几种破解MySQL root密码的几种方法: 方法一 使用phpmyadmin,这是最简单的了,修改mysql库的user表,不过别忘了使用PASSWord函数. 方法二 使用mysqladmin,这 ...
- NUMBER BASE CONVERSION(进制转换)
Description Write a program to convert numbers in one base to numbers in a second base. There are 62 ...
- 更改xcode上iphone模拟器颜色的方法--备用
到模拟器的目录下修改图片即可——在Finder中显示,显示模拟器包内容,修改Contents/Resources/frame.png图片!
- LDMFD和STMFD个人理解
ARM里面的堆栈是满递减(FULL DESCENDING)的.SP指向最后一个入栈的数据,SP的地址由高向低生长.对于LDM和STM指令来说,编号小的寄存器对应堆栈中的低地址. STMFD的寻址方式是 ...
- 探讨VMP 2.12.3 导入表修复
壳版本:VMProtect.Ultimate.2.12.3 样本:notepad.exe 目的:IAT修复 作者:MrWrong 标题:探讨VMP 2.12.3 导入表修复 只是感兴趣,没有其他目的. ...
- new Date参数问题
new Date支持的参数: MDN: new Date(); new Date(value); new Date(dateString); new Date(year, month, ...