linuxinotify
⑴ 怎样在linux内核中添加inotify
这个我们期末考试考过。
inotify只能监控单层目录变化,不能监控子目录中的变化情况。
如果需要监控子目录,需要在调用inotify_add_watch(int fd, char *dir, int mask):int建立监控时,递归建立子目录的监控,伪代码如下
void addwatch(int fd, char *dir, int mask)
{
wd = inotify_add_watch(fd, dir, mask);
向目录集合加入(wd, dir);
for (dir下所有的子目录subdir)
addwatch(fd, subdir, mask);
}
这样就可以得到一个目录集合,其中每一个wd对应一个子目录。
当你调用read获取信息时,可以得到一个下面的结构体
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. */
};
⑵ linux检测文件状态的inotifywait 无法开机启动
显示缺失文件如下:
systems\drivers\isapnp.sye
并显示要我通过安装盘中的"R"修复
希望大侠帮忙,小女万分感谢!
⑶ debian支持 inotify吗
支持。所有linux系统都支持inotify, 因为inotify是内核提供的功能。用户态程序都只是调用一下内核的接口而已。
⑷ linux inotify 监控一个图片文件夹,将新增的图片复制到另一个文件夹
本机复制还是复制到别的服务器
⑸ Linux gcc或者g++编程 下如何监视文件夹中文件的改变
从编程实现上来说,linux下做这个事情,要比windows上做简单,windows上有相关API提供接口,比如VC下的ReadDirectoryChanges函数,但其实它的功能并不是很完善,我之前曾经做过一个windows下类似的工具,如果要做到很完善的功能,要涉及到windows底层驱动。而linux下做这个事情就简单多了,从内核2.6.13开始,inotify编程接口就已经被加入到系统内核中,用来监控文件系统事件,它能监控到的事件包含文件/文件夹的新建,删除,修改,属性被修改,打开等等,功能比windows API提供的要丰富得多。在linux下输入man inotify即可查看该接口的编程手册,要实现对某个文件夹的监控,只需要使用该接口提供的inotify_init, inotify_add_watch, inotify_rm_watch三个函数即可。具体可以网络inotify,很容易就能找到相关示例代码。
附Linux下inotify编程接口部分截图:
点击图片可以看大图。
⑹ Linux下使用inotifywait来监控目录下的文件创建情况,有新文件创建就用硬链接的方式复制
http://blog.uouo123.com/post/103.html
这里有inotify的实操
⑺ 怎么查看linux是否安装inotify-tools成功
要看你使用的linux系统版本。
redhat系列的可以rpm -qa | grep 查询 。
ubuntu系列可以使用dpkg -l 来查询软件包的状态 。
⑻ linux inotify 最高监控多少
有时候我们需要检测某个目录下文件或者子目录的改动状况,如添加、删除、以及更新等,Linux系统上提供了inotify来完成这个功能。inotify是在版本2.6.13的内核中首次出现,现在的发行本应该都包含这个系统调用了。
下面的描述中的文件如无特别说明包括文件以及目录
使用inotify的第一步就是调用inotify_init()创建一个inotify实例,该函数返回一个文件描述符。这个文件描述符关联了一个inotify事件队列,通过read读取该文件描述符,就能获取底层的inotify事件。
1
int inotify_fd = inotify_init();
还有另外一个系统调用inotify_init1(int flag),该函数提供了一个参数可用于设置文件描述符属性
1
int inotify_fd = inotify_init1(flag);
其效果与如下代码相同
1
2
int inotify_fd = inotify_init();
fcntl(inotify_fd, F_SETFL, flags)
一旦成功创建了inotify实例,获得了相应的文件描述符,下一步就是告诉内核需要关注的文件以及关注的事件类型。这一步是通过函数inotify_add_watch()实现的。
1
int wd = inotify_add_watch(instance_fd, file_name, event_mask)
上面的调用中,file_name就是需要关注的文件,而event_mask是关注的事件类型掩码。目前inotify支持的事件类型包括如下几种
IN_ACCESS
IN_ATTRIB
IN_CLOSE_WRITE
IN_CLOSE_NOWRITE
IN_CREATE
IN_DELETE
IN_DELETE_SELF
IN_MODIFY
IN_MOVE_SELF
IN_MOVED_FROM
IN_MOVED_TO
IN_OPEN
这里面值得注意的是IN_DELETE、IN_MOVE_TO和IN_DELETE_SELF、IN_MOVE_SELF,简单来说带有SELF结尾的事件,发生在被关注目录自身,而不带SELF的发生在关注对象的子目录或者子文件之上。例如对于目录A调用inotify_add_watch,如果目录A中的文件B被删除,内核会发出IN_DELETE事件,而目录A被删除,内核发出IN_DELETE_SELF事件。
如果决定不再关注某个文件,只需调用inotify_rm_watch(instance_fd, wd)即可,其中的wd为inotify_add_watch的返回值。
设置好了关注文件以及事件类型,剩下的就是inotify事件的处理了。
首先第一步就是要获取inotify事件,这一步非常简单,只需要对于instance_fd调用read进行读取即可。注意,read读出的数据只是一些字符序列,你要通过强制转换才能获得inotify_event
1
2
3
4
5
6
7
struct inotify_event {
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name[]
};
具体的含义可以使用man命令去看,值得一体的是mask字段和cookie字段。这里的mask字段除了包含事件类型之外,还可能包含其他信息,诸如IN_ISDIR标示事件是否是发生在目录之上,IN_UMOUNT标示关注对象所在文件系统是否被卸载等。
Windows下也有类似的系统调用ReadDirectoryChanges,不过我在FreeBSD以及AIX下都未找到相应的系统调用
⑼ linux inotifywait能否获取到哪个文件改变了
显示缺失文件如下: systems\drivers\isapnp.sye 并显示要我通过安装盘中的"R"修复 希望大侠帮忙,小女万分感谢!
⑽ 在linux下使用inotify监控,能不能够知道监控目录下子目录中是哪个文件被修改了。。。求方法。。。
这个我们期末考试考过。
inotify只能监控单层目录变化,不能监控子目录中的变化情况。
如果需要监控子目录,需要在调用inotify_add_watch(int fd, char *dir, int mask):int建立监控时,递归建立子目录的监控,伪代码如下
void addwatch(int fd, char *dir, int mask)
{
wd = inotify_add_watch(fd, dir, mask);
向目录集合加入(wd, dir);
for (dir下所有的子目录subdir)
addwatch(fd, subdir, mask);
}
这样就可以得到一个目录集合,其中每一个wd对应一个子目录。
当你调用read获取信息时,可以得到一个下面的结构体
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. */
};
其中,通过event->wd和刚才记录的目录集合可以知道变动的具体子目录。
event->name为具体的文件名称。
event->name是一个char name[0]形式的桩指针,具体的name占据的长度可以由event->len得出
我的监控部分代码如下:
enum {EVENT_SIZE = sizeof(struct inotify_event)};
enum {BUF_SIZE = (EVENT_SIZE + 16) << 10};
void watch_mon(int fd)
{
int i, length;
void *buf;
struct inotify_event *event;
buf = malloc(BUF_SIZE);
while ((length = read(fd, buf, BUF_SIZE)) >= 0)
{
i = 0;
while (i < length)
{
event = buf + i;
if (event->len)
具体处理函数(event);
i += EVENT_SIZE + event->len;
}
}
close(fd);
exit(1);
}
在你的具体处理函数中,通过wd辨识子目录,通过name辨识文件
这是利用C++STLmap写的一个范例,可以监视当前目录下(含子目录)的变化,创建,删除过程(新建立的目录不能监视,只能通过监视到创建新目录的事件后重新初始化监视表)
新版1.1.0,可以监视创建的子目录,方法是,当do_action探测到新目录创建的动作时,调用inotify_add_watch追加新的监视
/*
Copyright (C) 2010-2011 LIU An ([email protected])
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <errno.h>
#include <dirent.h>
#include <map>
#include <string>
using namespace std;
void addwatch(int, char*, int);
static int filter_action(uint32_t mask);
int watch_init(int mask, char *root);
void addwatch(int fd, char *dir, int mask);
static void do_action(int fd, struct inotify_event *event);
void watch_mon(int fd);
static void send_mess(char *name, char *act, int ewd);
void append_dir(int fd, struct inotify_event *event, int mask);
map<int, string> dirset;
enum{MASK = IN_MODIFY | IN_CREATE | IN_DELETE};
int main(int argc, char **argv)
{
int fd;
if (argc != 2)
{
fprintf(stderr, "Usage: %s dir\n", argv[0]);
exit(1);
}
fd = watch_init(MASK, argv[1]);
watch_mon(fd);
return 0;
}
int watch_init(int mask, char *root)
{
int i, fd;
if ((fd = inotify_init()) < 0)
perror("inotify_init");
addwatch(fd, root, mask);
return fd;
}
void addwatch(int fd, char *dir, int mask)
{
int wd;
char subdir[512];
DIR *odir;
struct dirent *dent;
if ((odir = opendir(dir)) == NULL)
{
perror("fail to open root dir");
exit(1);
}
wd = inotify_add_watch(fd, dir, mask);
dirset.insert(make_pair(wd, string(dir)));
errno = 0;
while ((dent = readdir(odir)) != NULL)
{
if (strcmp(dent->d_name, ".") == 0
|| strcmp(dent->d_name, "..") == 0)
continue;
if (dent->d_type == DT_DIR)
{
sprintf(subdir, "%s/%s", dir, dent->d_name);
addwatch(fd, subdir, mask);
}
}
if (errno != 0)
{
perror("fail to read dir");
exit(1);
}
closedir (odir);
}
enum {EVENT_SIZE = sizeof(struct inotify_event)};
enum {BUF_SIZE = (EVENT_SIZE + 16) << 10};
void watch_mon(int fd)
{
int i, length;
void *buf;
struct inotify_event *event;
buf = malloc(BUF_SIZE);
while ((length = read(fd, buf, BUF_SIZE)) >= 0)
{
i = 0;
while (i < length)
{
event = (struct inotify_event*)(buf + i);
if (event->len)
do_action(fd, event);
i += EVENT_SIZE + event->len;
}
}
close(fd);
exit(1);
}
static char action[][10] =
{
"modified",
"accessed",
"created",
"removed"
};
enum{NEWDIR = IN_CREATE | IN_ISDIR};
static void do_action(int fd, struct inotify_event *event)
{
int ia, i;
if ((ia = filter_action(event->mask)) < 0)
return;
if ((event->mask & NEWDIR) == NEWDIR)
append_dir(fd, event, MASK);
send_mess(event->name, action[ia], event->wd);
}
void append_dir(int fd, struct inotify_event *event, int mask)
{
char ndir[512];
int wd;
sprintf(ndir, "%s/%s", dirset.find(event->wd)->second.c_str(),
event->name);
wd = inotify_add_watch(fd, ndir, mask);
dirset.insert(make_pair(wd, string(ndir)));
}
static int filter_action(uint32_t mask)
{
if (mask & IN_MODIFY)
return 0;
if (mask & IN_ACCESS)
return 1;
if (mask & IN_CREATE)
return 2;
if (mask & IN_DELETE)
return 3;
return -1;
}
static void send_mess(char *name, char *act, int ewd)
{
char format[] = "%s was %s.\n";
char file[512];
sprintf(file, "%s/%s", dirset.find(ewd)->second.c_str(), name);
printf(format, file, act);
}
参考资料是我们作业的提交,没有考虑递归创建子目录监控的问题。