问题检测文件移动使用​​inotify。

我想用inotify来监视一个目录的内容。 一切似乎很好,直到我尝试使用mv命令重命名目录中的文件。 按预期得到IN_MOVED_FROM,但是IN_MOVED_TO不来。

以下是我的testing程序。 编译:

g++ -Wall -o test test.cpp 

启动:

 ./test dir_to_watch 
 #include <cstdio> #include <cstring> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <sys/inotify.h> int main (int argc, char *argv[]) { int inotify_fd = inotify_init(); if (inotify_fd < 0) { fprintf(stderr, "Unable to init inotify: %m\n"); return 1; } int watch_descriptor = inotify_add_watch(inotify_fd, argv[1], IN_ALL_EVENTS); if (watch_descriptor < 0) { fprintf(stderr, "Unable to add inotify watch: %m\n"); return 1; } union { inotify_event event; char pad[1024]; } buffer; struct events { int mask; const char *name; } events[] = { {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 "}, }; while (read(inotify_fd, &buffer, sizeof buffer) > 0) { for (unsigned i = 0; i < sizeof events / sizeof events[0]; i++) { if (events[i].mask & buffer.event.mask) { if (buffer.event.len) { printf("Inotify %s: %s\n", events[i].name, buffer.event.name); } else { printf("Inotify %s\n", events[i].name); } } } } } 

自我解决:事实证明inotify可以在单个read()调用中返回多个事件。 所以纠正的源代码如下所示:

 #include <cstdio> #include <cstring> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <sys/inotify.h> int main (int argc, char *argv[]) { int inotify_fd = inotify_init(); if (inotify_fd < 0) { fprintf(stderr, "Unable to init inotify: %m\n"); return 1; } int watch_descriptor = inotify_add_watch(inotify_fd, argv[1], IN_ALL_EVENTS); if (watch_descriptor < 0) { fprintf(stderr, "Unable to add inotify watch: %m\n"); return 1; } struct events { int mask; const char *name; } events[] = { {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 "}, }; ssize_t rd; char buffer[1024]; while ((rd = read(inotify_fd, buffer, sizeof buffer)) > 0) { for (char *ptr = buffer; ptr != buffer + rd; ptr += sizeof(inotify_event) + reinterpret_cast<inotify_event*>(ptr)->len) { inotify_event *event = reinterpret_cast<inotify_event*>(ptr); for (unsigned i = 0; i < sizeof events / sizeof events[0]; i++) { if (events[i].mask & event->mask) { if (event->len) { printf("Inotify %d %s: %s\n", inotify_fd, events[i].name, event->name); } else { printf("Inotify %d %s\n", inotify_fd, events[i].name); } } } } } if (rd < 0) { fprintf(stderr, "inotify read %d event error: %m\n", inotify_fd); return 1; } }