當前位置:首頁 » 操作系統 » linuxinotify

linuxinotify

發布時間: 2022-02-16 12:43:52

⑴ 怎樣在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);
}

參考資料是我們作業的提交,沒有考慮遞歸創建子目錄監控的問題。

熱點內容
centosphp版本 發布:2024-12-26 23:11:59 瀏覽:70
安卓機怎麼關閉主題 發布:2024-12-26 21:55:57 瀏覽:915
javafor線程 發布:2024-12-26 21:54:35 瀏覽:744
python自定義模塊 發布:2024-12-26 21:41:37 瀏覽:57
linux安裝mysqltar 發布:2024-12-26 21:18:02 瀏覽:315
瀏覽器的java支持 發布:2024-12-26 21:15:45 瀏覽:655
電商高管如何配置 發布:2024-12-26 21:13:48 瀏覽:709
批發的演算法 發布:2024-12-26 21:13:46 瀏覽:208
安卓手機在日本下載哪個導航 發布:2024-12-26 21:09:32 瀏覽:560
白雜訊加密 發布:2024-12-26 20:31:02 瀏覽:641