问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

在linux下使用inotify监控,能不能够知道监控目录下子目录中是哪个文件被修改了。。。求方法。。。

发布网友 发布时间:2022-04-29 20:35

我来回答

2个回答

热心网友 时间:2023-10-08 22:09

这个我们期末考试考过。
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 (SuperHacker@china.com.cn)

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 copy 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);
}

参考资料是我们作业的提交,没有考虑递归创建子目录监控的问题。

参考资料:http://59.67.33.217/homeworkref/sources/2010-2011-1.2008.software.os.inotify.tar.xz

热心网友 时间:2023-10-08 22:09

你可以试试自己用 mingw 编译一个 DOS 下面可用的 tail 啊~

如果你用 windows 的 cmd 。可以看看 powershell 有没有这个命令。
或者尝试安装一个 cygwin ,里面我记得有这个命令。之后用 cywin 的 bash 命令行当命令行用。

你要是用纯 DOS ,貌似你可以放弃计算机了……
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
梦见和同性发生关糸了 梦见和同性朋友发生亲密关系 学生党如何科学护肤? 学生党该怎么基础护肤? 有什么美容护肤的技巧适合学生党? 怎么@全部成员啊? 新洲摩尔城一楼小吃租金多少 武汉王家湾有哪些广场 你好 请问 晚上6点开始 学瑜伽 可以吗? 因为我想在下班时间去 锻炼锻 ... 电脑联网有哪些条件台式电脑无线上网需要具备哪些条件 5G时代创新金融产品,泸州银行是如何做好行业服务“领跑者”的? 外汇交易实用技术指标有哪些? C盘文件tcu5bfbewd.dll删除不了怎么办? 跪求在ipad上看期货的软件,要免费的。看行情就可以了,不需要交易功能 初中数学怎么样复习 银行产品创意设计 股指期货软件怎么看? 为什么我的电脑刚刚重新安装后用ewido查就有病毒? 期货软件怎么看 &quot;WMSysPr9.prx&quot; 这是什么的文件? 广数928z轴输入10,实际只走了7,该怎么改脉冲倍乘比 我的电脑又蓝屏啦,这倒底是什么原因啊 入团志愿书入团介绍人意见 e盘文件全变0字节,空间没少,能进盘但无法打开0字节文件夹。 入团介绍人意见 怎么填 智能证件照相机怎么取消自动续费? 入团介绍人意见 海尔u80自身带的大智慧炒股软件支持横屏看K线走势图吗? 新团员入团介绍人意见怎么写才好??? 如何写入团介绍人意见? 中国学院 我的3ds max注册机算出来的激活码不对 外汇短线方法技术指标是什么? 外汇技术分析主要看哪些指标? 在理财方面你都有过哪些创意十足的想法? 我是做软件产品研发的,有没有好的产品创意? 激光打标机20W光纤的设备多少钱 光纤激光打标机20w最高功率调到多少 光纤激光打标机20W 多少钱一台 光纤激光打标机10W20W30W有什么区别吗 20W的激光打标机工作一小时大概要多少度电? 20w激光打标机与10w光纤打标机有什么不同 光纤激光打标机dl-ylp20w有什么危害性 20W激光打标机,能否用来制作移印机用的钢板? 光纤激光打标机20w激光聚焦光点温度多高 怎么分辨10w和20w的光纤激光打标机 男按摩师有前途吗? 男按摩师这个职业好吗 光纤激光打标机20w激光聚集光点温度多高 男足疗按摩师有前途吗???