精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何監控Linux文件系統事件:inotify使用指南

系統 Linux
當需要對Linux文件系統進行高效率、細粒度、異步地監控時,可以采用 inotify。可利用它對用戶空間進行安全、性能、以及其他方面的監控。inotify允許監控程序打開一個獨立文件描述符,并針對事件集監控一個或者多個文件,例如打開、關閉、移動/重命名、刪除、創建或者改變屬性。

從文件管理器到安全工具,文件系統監控對于的許多程序來說都是必不可少的。從 Linux 2.6.13 內核開始,Linux 就推出了 inotify,允許監控程序打開一個獨立文件描述符,并針對事件集監控一個或者多個文件,例如打開、關閉、移動/重命名、刪除、創建或者改變屬性。在后期的內核中有了很多增強,因此在依賴這些特性之前,請先檢查您的內核版本。

在本文中,您將會學習如何在簡單的監控應用程序中使用 inotify 功能。下載樣例代碼,在您的系統上編譯,進一步探索。

歷史簡介

在 inotify 之前有 dnotify。不幸的是,dnotify 有局限性,用戶需要更好的產品。和 dnotify 相比 inotify 的優勢如下:

  • Inotify 使用一個獨立的文件描述符,而 dnotify 需要為每個受監控的目錄打開一個文件描述符。當您同時監控多個目錄時成本會非常高,而且還會遇到每進程文件描述符限制。
  • Inotify 所使用的文件描述符可以通過系統調用獲得,并且沒有相關設備或者文件。而使用 dnotify,文件描述符就固定了目錄,妨礙備用設備卸載,這是可移動媒體的一個典型問題。對于 inotify,卸載的文件系統上的監視文件或目錄會產生一個事件,而且監視也會自動移除。
  • Inotify 能夠監視文件或者目錄。Dnotify 則只監視目錄,因此程序員還必須保持 stat 結構或者一個等效的數據結構,來反映該被監視目錄中的文件,然后在一個事件發生時,將其與當前狀態進行對比,以此了解當前目錄中的條目發生了什么情況。
  • 如上所述,inotify 使用文件描述符,允許程序員使用標準 select 或者 poll 函數來監視事件。這允許高效的多路復用 I/O 或者與 Glib 的 mainloop 的集成。相比之下,dnotify 使用信號,這使得程序員覺得比較困難或者不夠流暢。在 2.6.25 內核中 inotify 還添加了 Signal-drive I.O 通知功能。

用于 inotify 的 API

Inotify 提供一個簡單的 API,使用最小的文件描述符,并且允許細粒度監控。與 inotify 的通信是通過系統調用實現。可用的函數如下所示:

inotify_init
是用于創建一個 inotify 實例的系統調用,并返回一個指向該實例的文件描述符。
inotify_init1
與 inotify_init 相似,并帶有附加標志。如果這些附加標志沒有指定,將采用與 inotify_init 相同的值。
inotify_add_watch
增加對文件或者目錄的監控,并指定需要監控哪些事件。標志用于控制是否將事件添加到已有的監控中,是否只有路徑代表一個目錄才進行監控,是否要追蹤符號鏈接,是否進行一次性監控,當***事件出現后就停止監控。
inotify_rm_watch
從監控列表中移出監控項目。
read
讀取包含一個或者多個事件信息的緩存。
close
關閉文件描述符,并且移除所有在該描述符上的所有監控。當關于某實例的所有文件描述符都關閉時,資源和下層對象都將釋放,以供內核再次使用。

因此,典型的監控程序需要進行如下操作:

  1. 使用 inotify_init 打開一個文件描述符
  2. 添加一個或者多個監控
  3. 等待事件
  4. 處理事件,然后返回并等待更多事件
  5. 當監控不再活動時,或者接到某個信號之后,關閉文件描述符,清空,然后退出。

在下一部分中,您將看到可以監控的事件,它們如何在簡單的程序中運行。***,您將看到事件監控如何進行。

#p#

通告

當您的應用程序讀取到一個通告時,事件的順序也被讀取到您提供的緩存中。事件在一個變長結構中被返回,如清單 1 所示。如果數據占滿了您的緩存,您可能需要對***一個條目進行局部事件信息或者局部名處理。

清單 1. 用于 inotify 的事件結構體
 

				
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.  */
  };

請注意,只有當監控對象是一個目錄并且事件與目錄內部相關項目有關,而與目錄本身無關時,才提供 name 字段。如果 IN_MOVED_FROM 事件與相應的 IN_MOVED_TO 事件都與被監控的項目有關,cookie 就可用于將兩者關聯起來。事件類型在掩碼字段中返回,并伴隨著能夠被內核設置的標志。例如,如果事件與目錄有關,則標志 IN_ISDIR 將由內核設置。

可監控的事件

有幾種事件能夠被監控。一些事件,比如 IN_DELETE_SELF 只適用于正在被監控的項目,而另一些,比如 IN_ATTRIB 或者 IN_OPEN 則只適用于監控過的項目,或者如果該項目是目錄,則可以應用到其所包含的目錄或文件。

IN_ACCESS
被監控項目或者被監控目錄中的條目被訪問過。例如,一個打開的文件被讀取。
IN_MODIFY
被監控項目或者被監控目錄中的條目被修改過。例如,一個打開的文件被修改。
IN_ATTRIB
被監控項目或者被監控目錄中條目的元數據被修改過。例如,時間戳或者許可被修改。
IN_CLOSE_WRITE
一個打開的,等待寫入的文件或目錄被關閉。
IN_CLOSE_NOWRITE
一個以只讀方式打開的文件或目錄被關閉。
IN_CLOSE
一個掩碼,可以很便捷地對前面提到的兩個關閉事件(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)進行邏輯操作。
IN_OPEN
文件或目錄被打開。
IN_MOVED_FROM
被監控項目或者被監控目錄中的條目被移出監控區域。該事件還包含一個 cookie 來實現 IN_MOVED_FROM 與 IN_MOVED_TO 的關聯。
IN_MOVED_TO
文件或目錄被移入監控區域。該事件包含一個針對 IN_MOVED_FROM 的 cookie。如果文件或目錄只是被重命名,將能看到這兩個事件,如果它只是被移入或移出非監控區域,將只能看到一個事件。如果移動或重命名一個被監控項目,監控將繼續進行。參見下面的 IN_MOVE-SELF。
IN_MOVE
可以很便捷地對前面提到的兩個移動事件(IN_MOVED_FROM | IN_MOVED_TO)進行邏輯操作的掩碼。
IN_CREATE
在被監控目錄中創建了子目錄或文件。
IN_DELETE
被監控目錄中有子目錄或文件被刪除。
IN_DELETE_SELF
被監控項目本身被刪除。監控終止,并且將收到一個 IN_IGNORED 事件。
IN_MOVE_SELF
監控項目本身被移動。

除了事件標志以外,還可以在 inotify 頭文件(/usr/include/sys/inotify.h)中找到其他幾個標志。例如,如果只想監控***個事件,可以在增加監控時設置 IN_ONESHOT 標志。

#p#

一個簡單的 inotify 應用程序

這里的簡單應用程序(參見 下載 部分)遵循以上的通用邏輯。我們使用一個信號處理程序來監控 ctrl-c(SIGINT)并且重置一個標志(keep_running)使應用程序了解終止操作。真實的 inotify 調用在 utility 例程當中完成。注意,我們還創建了一個隊列,這樣能夠將事件從 inotify 底層對象中清除,留著稍后處理。在真實的應用程序中,您可能想用一個不同于您處理事件所用的線程(具有更高優先級)來完成這一操作。對于該應用程序,只是為了對一般原理進行舉例說明。我們采用了一個簡單的事件鏈表,在其中我們隊列中的每個條目都包含原始事件以及指向隊列中下一事件指針的空間。

主程序

清單 2 中展示了信號處理例程和主例程。在這個簡單示例中,在命令行對每個傳遞進來的文件會目錄建立監控,并利用事件掩碼 IN_ALL_EVENTS 來監控每個對象的所有事件。在真實的應用程序中,您可能只希望跟蹤文件與目錄的創建或刪除事件,因此您可以屏蔽打開、關閉以及屬性改變事件。如果您對文件或目錄的重命名和移動不感興趣,您也可以屏蔽各種移動事件。關于更多細節,參見 inotify 幫助信息。

清單 2. inotify-test.c 的簡單主程序
 

				
/* Signal handler that simply resets a flag to cause termination */
void signal_handler (int signum)
{
  keep_running = 0;
}

int main (int argc, char **argv)
{
  /* This is the file descriptor for the inotify watch */
  int inotify_fd;

  keep_running = 1;

  /* Set a ctrl-c signal handler */
  if (signal (SIGINT, signal_handler) == SIG_IGN)
    {
      /* Reset to SIG_IGN (ignore) if that was the prior state */
      signal (SIGINT, SIG_IGN);
    }

  /* First we open the inotify dev entry */
  inotify_fd = open_inotify_fd ();
  if (inotify_fd > 0)
    {

      /* We will need a place to enqueue inotify events,
         this is needed because if you do not read events
         fast enough, you will miss them. This queue is 
         probably too small if you are monitoring something
         like a directory with a lot of files and the directory 
         is deleted.
       */
      queue_t q;
      q = queue_create (128);

      /* This is the watch descriptor returned for each item we are 
         watching. A real application might keep these for some use 
         in the application. This sample only makes sure that none of
         the watch descriptors is less than 0.
       */
      int wd;


      /* Watch all events (IN_ALL_EVENTS) for the directories and 
         files passed in as arguments.
         Read the article for why you might want to alter this for 
         more efficient inotify use in your app.      
       */
      int index;
      wd = 0;
      printf("\n");
      for (index = 1; (index < argc) && (wd >= 0); index++) 
	{
	  wd = watch_dir (inotify_fd, argv[index], IN_ALL_EVENTS);
	}

      if (wd > 0) 
	{
	  /* Wait for events and process them until a 
         termination condition is detected
 	  */
	  process_inotify_events (q, inotify_fd);
	}
      printf ("\nTerminating\n");

      /* Finish up by closing the fd, destroying the queue,
         and returning a proper code
       */
      close_inotify_fd (inotify_fd);
      queue_destroy (q);
    }
  return 0;
}

使用 inotify_init 打開文件描述符

清單 3 展示了用于創建 inotify 實例以及獲取其文件描述符的簡單實用工具函數。文件描述符返回給了調用者。如果出現錯誤,返回值將為負。

清單 3. 使用 inotify_init
 

				
/* Create an inotify instance and open a file descriptor
   to access it */
int open_inotify_fd ()
{
  int fd;

  watched_items = 0;
  fd = inotify_init ();

  if (fd < 0)
    {
      perror ("inotify_init () = ");
    }
  return fd;
  }

使用 inotify_add_watch 添加一個監控

一旦我們有了用于 inotify 實例的文件描述符之后,就需要增加一個或多個監控。您可以使用掩碼來設置想要監控的事件。在本例中,采用掩碼 IN_ALL_EVENTS,來監控所有可用事件。

清單 4. 使用 inotify_add_watch
 

				
int watch_dir (int fd, const char *dirname, unsigned long mask)
{
  int wd;
  wd = inotify_add_watch (fd, dirname, mask);
  if (wd < 0)
    {
      printf ("Cannot add watch for \"%s\" with event mask %lX", dirname,
	      mask);
      fflush (stdout);
      perror (" ");
    }
  else
    {
      watched_items++;
      printf ("Watching %s WD=%d\n", dirname, wd);
      printf ("Watching = %d items\n", watched_items); 
    }
  return wd;
}
            

事件處理循環

現在我們已經設置了一些監控,接下來就要等待事件。如果還存在監控,并且 keep_running 標志沒有被信號處理程序重置,則循環會一直進行。循環進程等待事件的發生,對有效事件進行排隊,并在返回等待狀態之前處理隊列。在真實應用程序當中,您可能會將事件放入線程隊列中,而在另一個線程中處理它們,清單 5 展示了該循環。

清單 5. 事件處理循環
 

				
int process_inotify_events (queue_t q, int fd)
{
  while (keep_running && (watched_items > 0))
    {
      if (event_check (fd) > 0)
	{
	  int r;
	  r = read_events (q, fd);
	  if (r < 0)
	    {
	      break;
	    }
	  else
	    {
	      handle_events (q);
	    }
	}
    }
  return 0;
  }

等待事件

在我們的示樣例應用程序中,循環會不停地進行下去,直至監控事件出現或者收到了中斷信號。清單 6 展示了相關代碼。

清單 6. 等待事件或者中斷
 

				
int event_check (int fd)
{
  fd_set rfds;
  FD_ZERO (&rfds);
  FD_SET (fd, &rfds);
  /* Wait until an event happens or we get interrupted 
     by a signal that we catch */
  return select (FD_SETSIZE, &rfds, NULL, NULL, NULL);
  }

讀取事件

當事件發生時,程序會依照緩存區的大小來讀取盡量多的事件,然后把這些事件放入隊列等待事件處理程序來處理。樣例代碼不能處理這種情況 — 可用事件超出 16.384 byte 緩存中可存儲的事件。要處理這類情況,需要在緩存末端處理部分事件。目前,對名字長度進行限制不成問題,但是優秀的防御式編程會檢查名字,來確保不會溢出緩存。

清單 7. 讀取事件并排隊
 

				
int read_events (queue_t q, int fd)
{
  char buffer[16384];
  size_t buffer_i;
  struct inotify_event *pevent;
  queue_entry_t event;
  ssize_t r;
  size_t event_size, q_event_size;
  int count = 0;

  r = read (fd, buffer, 16384);
  if (r <= 0)
    return r;
  buffer_i = 0;
  while (buffer_i < r)
    {
      /* Parse events and queue them. */
      pevent = (struct inotify_event *) &buffer[buffer_i];
      event_size =  offsetof (struct inotify_event, name) + pevent->len;
      q_event_size = offsetof (struct queue_entry, inot_ev.name) + 
                                  pevent->len;
      event = malloc (q_event_size);
      memmove (&(event->inot_ev), pevent, event_size);
      queue_enqueue (event, q);
      buffer_i += event_size;
      count++;
    }
  printf ("\n%d events queued\n", count);
  return count;
}

處理事件

***,我們需要對事件做處理了。對于該應用程序,我們只簡單地報告所發生的事件。如果一個名字出現在事件結構中,我們就報告它是一個文件或目錄。發生移動時,還會報告與移動或重命名事件相關的 cookie 信息。清單 8 展示了部分代碼,包括對一些事件的處理。參見 下載 部分可獲取完整代碼。

清單 8. 處理事件
 

				
void handle_event (queue_entry_t event)
{
  /* If the event was associated with a filename, we will store it here */
  char *cur_event_filename = NULL;
  char *cur_event_file_or_dir = NULL;
  /* This is the watch descriptor the event occurred on */
  int cur_event_wd = event->inot_ev.wd;
  int cur_event_cookie = event->inot_ev.cookie;

  unsigned long flags;

  if (event->inot_ev.len)
    {
      cur_event_filename = event->inot_ev.name;
    }
  if ( event->inot_ev.mask & IN_ISDIR )
    {
      cur_event_file_or_dir = "Dir";
    }
  else 
    {
      cur_event_file_or_dir = "File";
    }
  flags = event->inot_ev.mask & 
    ~(IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED );

  /* Perform event dependent handler routines */
  /* The mask is the magic that tells us what file operation occurred */
  switch (event->inot_ev.mask & 
	  (IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED))
    {
      /* File was accessed */
    case IN_ACCESS:
      printf ("ACCESS: %s \"%s\" on WD #%i\n",
	      cur_event_file_or_dir, cur_event_filename, cur_event_wd);
      break;

      /* File was modified */
    case IN_MODIFY:
      printf ("MODIFY: %s \"%s\" on WD #%i\n",
	      cur_event_file_or_dir, cur_event_filename, cur_event_wd);
      break;

      /* File changed attributes */
    case IN_ATTRIB:
      printf ("ATTRIB: %s \"%s\" on WD #%i\n",
	      cur_event_file_or_dir, cur_event_filename, cur_event_wd);
      break;

      /* File open for writing was closed */
    case IN_CLOSE_WRITE:
      printf ("CLOSE_WRITE: %s \"%s\" on WD #%i\n",
	      cur_event_file_or_dir, cur_event_filename, cur_event_wd);
      break;

      /* File open read-only was closed */
    case IN_CLOSE_NOWRITE:
      printf ("CLOSE_NOWRITE: %s \"%s\" on WD #%i\n",
	      cur_event_file_or_dir, cur_event_filename, cur_event_wd);
      break;

      /* File was opened */
    case IN_OPEN:
      printf ("OPEN: %s \"%s\" on WD #%i\n",
	      cur_event_file_or_dir, cur_event_filename, cur_event_wd);
      break;

      /* File was moved from X */
    case IN_MOVED_FROM:
      printf ("MOVED_FROM: %s \"%s\" on WD #%i. Cookie=%d\n",
	      cur_event_file_or_dir, cur_event_filename, cur_event_wd, 
              cur_event_cookie);
      break;
.
. (other cases)
.
      /* Watch was removed explicitly by inotify_rm_watch or automatically
         because file was deleted, or file system was unmounted.  */
    case IN_IGNORED:
      watched_items--;
      printf ("IGNORED: WD #%d\n", cur_event_wd);
      printf("Watching = %d items\n",watched_items); 
      break;

      /* Some unknown message received */
    default:
      printf ("UNKNOWN EVENT \"%X\" OCCURRED for file \"%s\" on WD #%i\n",
	      event->inot_ev.mask, cur_event_filename, cur_event_wd);
      break;
    }
  /* If any flags were set other than IN_ISDIR, report the flags */
  if (flags & (~IN_ISDIR))
    {
      flags = event->inot_ev.mask;
      printf ("Flags=%lX\n", flags);
    }
    }

這個簡單示例用于說明 inotify 如何工作,以及您可以監控什么事件。您的實際需求將決定對哪些事件進行監控以及如何處理這些事件。

#p#

用法舉例

在本部分中,我們創建一個帶有文件的簡單雙級目錄結構,然后運行簡單程序來舉例說明 inotify 所能監控的一些事件。我們將在終端會話中啟動 inotify 示例程序,但是在后臺運行(使用 &)因此程序的輸出與我們輸入的命令會交替出現。您可以在一個終端窗口運行該程序,而在其他一個或多個窗口運行指令。清單 9 展示了簡單文件結構和空文件的創建,以及最初啟動該示例程序時的輸出。

清單 9. 創建一個樣例環境
 

				
ian@attic4:~/inotify-sample$ mkdir -p dir1/dir2
ian@attic4:~/inotify-sample$ touch dir1/dir2/file1
ian@attic4:~/inotify-sample$ ./inotify_test dir1/ dir1/dir2/ dir1/dir2/file1&
[2] 8733
ian@attic4:~/inotify-sample$ 
Watching dir1/ WD=1
Watching = 1 items
Watching dir1/dir2/ WD=2
Watching = 2 items
Watching dir1/dir2/file1 WD=3
Watching = 3 items

ian@attic4:~/inotify-sample$ 
            

在清單 10 中,展示了來自 dir2 內容清單的輸出。***個事件報告是關于 dir1 的,展示了一些內容,即 dir2 ,在被監控描述符 1 監控的目錄當中被打開了。第二個條目是關于監控描述符 2 的,顯示出被監控項目(在本例中為 dir2 )被打開了。如果正在監控目錄樹中的多個項目,可能會經常遇到這種雙重輸出。

清單 10. 列舉 dir2 的內容
 

				
ian@attic4:~/inotify-sample$ ls dir1/dir2
file1

4 events queued
OPEN: Dir "dir2" on WD #1
OPEN: Dir "(null)" on WD #2
CLOSE_NOWRITE: Dir "dir2" on WD #1
CLOSE_NOWRITE: Dir "(null)" on WD #2

在清單 11 中,我們在 file1 添加了一些文本。請再次注意對文件以及該文件所在目錄的雙重打開、關閉和修改事件。還請注意所有的事件并非立刻讀取。排隊例程被調用了3次,每次有兩個事件。如果再次運行該程序,并且每次操作相同,您未必會再次遇到這一特別情況。

清單 11. 在 file1 中添加文本
 

				
ian@attic4:~/inotify-sample$ echo "Some text" >> dir1/dir2/file1

2 events queued
OPEN: File "file1" on WD #2
OPEN: File "(null)" on WD #3

2 events queued
MODIFY: File "file1" on WD #2
MODIFY: File "(null)" on WD #3

2 events queued
CLOSE_WRITE: File "file1" on WD #2
CLOSE_WRITE: File "(null)" on WD #3

在清單 12 中,我們改變了 file1 的屬性。我們再次得到有關被監控項目以及其所在目錄的雙重輸出。

清單 12. 改變文件屬性
 

				
ian@attic4:~/inotify-sample$ chmod a+w dir1/dir2/file1

2 events queued
ATTRIB: File "file1" on WD #2
ATTRIB: File "(null)" on WD #3

現在將文件 file1 移動到上一級目錄 dir1 當中。在清單 13 中顯示了輸出結果。這次沒有雙重條目。我們實際上得到了 3 個條目,每個目錄一個,文件本身一個。請注意 cookie (569) 允許將 MOVED-FROM 事件與 MOVED_TO 事件關聯起來。

清單 13. 將 file1 移動到 dir1
 

				
ian@attic4:~/inotify-sample$ mv dir1/dir2/file1 dir1

3 events queued
MOVED_FROM: File "file1" on WD #2. Cookie=569
MOVED_TO: File "file1" on WD #1. Cookie=569
MOVE_SELF: File "(null)" on WD #3

現在創建一個 file1 到 file2 的硬鏈接。當到 inode 的鏈接數量該變時,我們會有一個關于 file1 的 ATTRIB 事件,還會有一個關于 file2 的 CREATE 事件。

清單 14. 創建硬鏈接
 

				
ian@attic4:~/inotify-sample$ ln dir1/file1 dir1/file2

2 events queued
ATTRIB: File "(null)" on WD #3
CREATE: File "file2" on WD #1

現在將文件 file1 移入當前目錄,將其重命名為 file3 。當前目錄沒有被監控,因此不存在與 MOVED_FROM 事件相關聯的 MOVED_TO 事件。

清單 15. 將 file1 移入不受監控的目錄當中
 

				
ian@attic4:~/inotify-sample$ mv dir1/file1 ./file3

2 events queued
MOVED_FROM: File "file1" on WD #1. Cookie=572
MOVE_SELF: File "(null)" on WD #3

此時,dir2 是空的,因此可以移動它。注意我們得到一個關于監控描述符 2 的 IGNORED 事件,可見現在我們只監控兩個項目。

清單 16. 移除 dir2
 

				
ian@attic4:~/inotify-sample$ rmdir dir1/dir2

3 events queued
DELETE: Dir "dir2" on WD #1
DELETE_SELF: File "(null)" on WD #2
IGNORED: WD #2
Watching = 2 items

移除文件 file3。注意這次我們沒有得到 IGNORED 事件。為什么呢?為什么得到了關于 file 3 的 ATTRIB 事件(就是原來的 dir1/dir2/file1)?

清單 16. 刪除 file3
 

				
ian@attic4:~/inotify-sample$ rm file3

1 events queued
ATTRIB: File "(null)" on WD #3

記住我們創建了 file1 到 file2 的硬鏈接。清單 17 顯示我們還在通過監控描述符 3 來監控 file2,盡管最開始不存在文件 2!

				
ian@attic4:~/inotify-sample$ touch dir1/file2

6 events queued
OPEN: File "file2" on WD #1
OPEN: File "(null)" on WD #3
ATTRIB: File "file2" on WD #1
ATTRIB: File "(null)" on WD #3
CLOSE_WRITE: File "file2" on WD #1
CLOSE_WRITE: File "(null)" on WD #3

因此,現在讓我們來刪除 dir1,并監控事件級聯,因為它不再監控任何事情,不得不結束了自己。

清單 18. 刪除 dir1
 

				
ian@attic4:~/inotify-sample$ rm -rf dir1

8 events queued
OPEN: Dir "(null)" on WD #1
ATTRIB: File "(null)" on WD #3
DELETE_SELF: File "(null)" on WD #3
IGNORED: WD #3
Watching = 1 items
DELETE: File "file2" on WD #1
CLOSE_NOWRITE: Dir "(null)" on WD #1
DELETE_SELF: File "(null)" on WD #1
IGNORED: WD #1
Watching = 0 items

Terminating

#p#

inotify 的可能使用

您可以將 inotify 用于多種目標。下面列舉一些可能的情況:

性能監控
您可能想確定應用程序打開最頻繁的文件是哪個。如果發現一個小文件被頻繁打開與關閉,您可能會考慮采用內存版,或者改變應用程序來采取其他方式共享該數據。
元信息
您可能想記錄文件的附加信息,例如起始創建時間或者***改變該文件的用戶 id。
安全
您可能會因為安全原因,需要對特定文件或目錄的所有訪問進行監控。

我們的示例代碼監控所有事件并進行報告。實際上,您可能想依據您的需要,來查看這些事件的特定子集。您可能想監控不同被監控項目的不同事件。例如,您可能想監控文件的打開與關閉事件,但對于目錄只想監控創建與刪除事件。在任何可能的時候,您可以監控您所感興趣的最小事件集。

結束語

應用到性能監控、程序調試、以及自動化等領域時,inotify 是監控 Linux 文件系統的功能強大的、高粒度的機制。利用本文提供的樣例代碼,您可以開始編寫用來實時記錄文件系統事件并最小化性能開銷的應用程序。

責任編輯:yangsai 來源: IBMDW
相關推薦

2010-05-07 15:40:18

ibmdwLinux

2010-05-10 15:14:13

inotifyLinux文件系統

2009-10-28 12:05:32

linux監控技術

2017-12-04 13:30:12

Linux文件系統鏈接

2015-05-19 11:11:29

JavaScript事件使用指南

2020-10-29 08:34:48

Linux - tmp

2018-05-02 08:35:33

LinuxTripwire文件系統

2009-12-10 09:42:07

2015-08-03 09:20:24

2024-02-04 00:00:00

Loki性能查詢

2011-01-13 14:10:30

Linux文件系統

2019-01-29 10:43:59

Linux 系統 數據

2022-09-29 09:07:08

DataGrip數據倉庫數據庫

2020-07-22 14:53:06

Linux系統虛擬文件

2019-03-04 14:40:46

Linux文件系統修復

2017-04-20 14:55:36

LinuxPyinotifyPython

2010-03-16 14:42:16

linux環境

2009-12-14 13:33:31

linuxramdisk文件系統

2021-04-12 05:44:44

Linux文件系統

2021-06-06 16:55:22

Linux文件系統
點贊
收藏

51CTO技術棧公眾號

国产中文字幕在线视频| 国产毛片aaa| 国产精品1区| 亚洲成精国产精品女| 欧美一区二区三区精美影视| 国产精品视频久久久久久| 国产精品videosex极品| 精品亚洲夜色av98在线观看| 亚洲欧美偷拍另类| 成人性生交大片免费看在线播放| 国产亚洲精品超碰| 99se婷婷在线视频观看| 国产精品国产三级国产专区52| 日韩免费一区| 亚洲精品理论电影| 手机免费av片| 亚洲欧美se| 亚洲黄网站在线观看| 日韩福利一区二区三区| 亚洲经典一区二区三区| 日韩va亚洲va欧美va久久| 欧美激情伊人电影 | 欧美韩国日本| 精品久久久精品| 亚洲一区二区三区四区的| 欧美与黑人午夜性猛交久久久| 国产人与禽zoz0性伦| 国产美女撒尿一区二区| 欧美精品tushy高清| 日韩视频第二页| 色黄网站在线观看| 国产精品美女一区二区| 欧美日韩国产不卡在线看| 不卡的日韩av| 国产一区二区91| 国产精品高潮视频| 五月婷婷中文字幕| 在线看片一区| 久久99热这里只有精品国产| 一二三四在线观看视频| 一区二区三区四区在线看| 欧美sm极限捆绑bd| 杨幂一区二区国产精品| 深夜福利亚洲| 欧美久久久一区| 宅男噜噜噜66国产免费观看| 伊人久久视频| 日韩欧美亚洲一二三区| 免费成人在线视频网站| www在线观看黄色| 亚洲成av人片在线观看| 99久久久精品视频| 一二三四区在线观看| 中文字幕在线观看一区| 亚洲国内在线| 免费网站成人| 成人欧美一区二区三区白人| 夜夜爽99久久国产综合精品女不卡 | 成人精品久久一区二区三区| 中国女人一级一次看片| 日韩在线一二三区| 国产精品久久久久久久7电影| 精品国产一区二区三区四| 国产精品资源| 日本中文字幕久久看| av图片在线观看| 丝袜亚洲另类欧美| 国产国语videosex另类| 小泽玛利亚一区二区三区视频| 日日骚欧美日韩| 国产精品爽黄69天堂a| 一道本无吗一区| 国产麻豆91精品| 国产成人免费观看| 香蕉视频网站在线| 国产欧美一区二区精品秋霞影院| 色999日韩自偷自拍美女| 在线看的av网站| 亚洲欧美日韩成人高清在线一区| 99亚洲国产精品| 91超碰在线| 色天使久久综合网天天| 奇米影视四色在线| 欧美片网站免费| 亚洲精品98久久久久久中文字幕| 亚洲国产av一区| 国产精品黑丝在线播放| 色综合色综合久久综合频道88| 国产第一页在线播放| 久久影院亚洲| 97视频资源在线观看| 亚洲日本中文字幕在线| 国产精品久久久久久久岛一牛影视 | www.久久国产| 国产精品99在线观看| 欧美黄色小视频| 免费看污视频的网站| 国产一区二区三区免费播放| 久久96国产精品久久99软件| 伊人在线视频| 偷偷要91色婷婷| 57pao国产成永久免费视频| 7m精品国产导航在线| 亚洲欧洲在线播放| 青青草激情视频| 久久综合图片| 国产传媒一区二区| jzzjzzjzz亚洲成熟少妇| 一区二区三区在线观看网站| 茄子视频成人免费观看| 精品三级国产| 亚洲人在线观看| 国产精品成人免费一区二区视频| 强制捆绑调教一区二区| 国产日韩三区| 国产1区在线| 91久久国产综合久久| 中文字幕永久免费| 日韩1区2区| 日韩av成人在线| 免费看黄网站在线观看| 国产精品护士白丝一区av| 免费无码不卡视频在线观看| 久久天堂久久| 中文字幕精品网| 少妇太紧太爽又黄又硬又爽| 大胆亚洲人体视频| 日本免费黄色小视频| 嫩草伊人久久精品少妇av杨幂| 亚洲高清久久网| 麻豆changesxxx国产| 久久超级碰视频| 亚洲精品中字| 国产极品久久久久久久久波多结野| 精品国产乱码久久久久久浪潮| 51精品免费网站| 免费在线看一区| 日本在线免费观看一区| 自拍偷拍欧美视频| 日韩av最新在线观看| 国产在线拍揄自揄拍无码视频| 黄页网站大全一区二区| 亚洲丰满在线| 日本综合视频| 中文字幕av一区二区| 天天综合久久综合| 国产欧美一区二区精品久导航| 老熟妇仑乱视频一区二区| 国产欧美日韩精品一区二区三区| 日本成人激情视频| 全色精品综合影院| 在线这里只有精品| 97在线观看免费视频| 日韩国产精品91| 杨幂一区欧美专区| 亚洲男人在线| 欧美日韩国产成人| 亚洲国产精品二区| 激情懂色av一区av二区av| 97人妻精品一区二区三区免费| 亚洲福利精品| 久久艳妇乳肉豪妇荡乳av| 亚洲免费福利| 在线性视频日韩欧美| 波多野结衣视频免费观看| 国产欧美一区二区精品仙草咪| 久久99999| 亚洲午夜精品一区 二区 三区| 99国产盗摄| 欧美一级鲁丝片| 亚洲一区二区福利| 一区二区三区免费在线| 亚洲欧洲制服丝袜| 国产艳妇疯狂做爰视频| 午夜一级久久| 日本黄色播放器| 日韩08精品| 欧美亚洲国产日本| 992tv免费直播在线观看| 91精品国产品国语在线不卡| 国产大片aaa| 国产精品天美传媒| 在线观看视频在线观看| av不卡免费看| 中文字幕不卡每日更新1区2区| 最新国产精品精品视频| 日韩av电影中文字幕| 麻豆传媒在线观看| 亚洲国产欧美一区二区三区同亚洲 | 欧美极品videos大乳护士| 日韩精品在线观| 国产精品乱码一区二区| 亚洲福利视频导航| 亚洲av熟女国产一区二区性色| 狠狠色伊人亚洲综合成人| 六月婷婷在线视频| 日本久久一二三四| 成人做爰66片免费看网站| 精品91久久| 欧美精品在线视频观看| 欧美美女搞黄| 日韩女优av电影| 国产成人精品一区二区色戒| 亚洲一区二区三区在线播放| avhd101老司机| 成人动漫一区二区在线| 亚洲欧美偷拍另类| 亚洲专区一区二区三区| 欧美极品少妇无套实战| 成人免费看片39| 久久久久高清| 91久久精品无嫩草影院| 国产精品最新在线观看| 中国字幕a在线看韩国电影| 欧美美女15p| 瑟瑟视频在线| 国产一区二区久久精品| 天堂中文在线看| 日韩一二三四区| ,亚洲人成毛片在线播放| 色综合中文综合网| 久久亚洲国产成人精品性色| 国产精品美女一区二区三区| 国产成人av一区二区三区不卡| 国产成a人亚洲| 亚洲男人天堂2021| 久久精品国产在热久久| 91色国产在线| 久久久久看片| 1024av视频| 亚洲经典三级| 日韩精品一区在线视频| 欧美激情在线| 天天想你在线观看完整版电影免费| 久久一区91| 亚洲日本无吗高清不卡| 波多野结衣在线播放一区| 久久精品一二三区| 欧美日韩看看2015永久免费 | 六月丁香婷婷在线| 在线国产欧美| 国产免费观看高清视频| 国产精品分类| 一卡二卡三卡视频| 极品尤物久久久av免费看| 国产91沈先生在线播放| 国产精品成人一区二区网站软件| 日韩成人午夜影院| 综合视频在线| www.国产二区| 伊人久久大香线蕉综合热线| 国产夫妻自拍一区| 亚洲欧洲一级| 日本福利视频在线| 国产精品久久久久9999高清| 国产精品后入内射日本在线观看| 国产精品日本欧美一区二区三区| 欧美在线观看成人| 久久精品30| 中文字幕在线观看第三页| 麻豆精品新av中文字幕| 九九九九九国产| 国产精品资源在线| 亚洲日本久久久| www..com久久爱| 人妻大战黑人白浆狂泄| 中文无字幕一区二区三区 | 凸凹人妻人人澡人人添| 日韩成人av在线播放| 男人的天堂在线视频| 最近2019中文字幕一页二页 | 亚洲三级在线免费观看| 青娱乐国产在线视频| 亚洲成人在线观看视频| 天天操天天操天天操天天| 欧美性猛交丰臀xxxxx网站| 无码无套少妇毛多18pxxxx| 欧美精品在线观看播放| www.成人精品| 精品调教chinesegay| a√资源在线| 欧美高清视频在线| 欧美激情网站| 成人黄色av播放免费| 成人av动漫| 日韩偷拍一区二区| 午夜激情一区| 国产日韩成人内射视频| 国产精品资源在线观看| 免费观看一级一片| 国产精品黄色在线观看| 国产成人无码精品久在线观看 | 国产高潮在线观看| 亚洲娇小xxxx欧美娇小| 永久免费av在线| 97精品在线观看| 亚洲狼人在线| 美女主播视频一区| 一区二区日韩欧美| 草草草在线视频| 国产成人亚洲综合a∨婷婷| 免费在线观看污| 一个色综合网站| 在线免费观看视频网站| 亚洲国产另类久久精品| 国产成人午夜| 国产精品视频男人的天堂| 51精品国产| 三年中文高清在线观看第6集| 亚洲综合不卡| 亚洲成年人在线观看| 国产精品网站在线播放| av黄色在线看| 精品sm捆绑视频| 国产激情在线视频| 国产精品户外野外| 网红女主播少妇精品视频| 蜜桃网站在线观看| 麻豆91精品视频| 男人操女人动态图| 午夜欧美大尺度福利影院在线看| 国产精品爽爽久久| 国产亚洲精品美女久久久久| 国产不卡123| 丁香五月网久久综合| 亚洲综合专区| 波多野结衣国产精品| 中文字幕免费不卡在线| 国产午夜无码视频在线观看 | 国产亚洲无码精品| 亚洲国产你懂的| av男人天堂网| 久热精品视频在线免费观看 | 99高清视频有精品视频| 91成人影院| www.国产福利| 亚洲男人天堂av| 国产露脸无套对白在线播放| 日韩小视频网址| 日韩专区视频| 综合久久国产| 国产麻豆91精品| 欧美成人国产精品高潮| 欧美成人一区二区三区片免费| 中文字幕在线三区| 91pron在线| 欧美精品国产一区| 免费在线观看日韩av| 亚洲综合色成人| 二区三区在线视频| 亚州成人av在线| 亚洲ab电影| 999精品网站| 欧美激情在线免费观看| 进去里视频在线观看| 中文字幕日本精品| 中文成人激情娱乐网| 手机在线视频你懂的| 国产一区欧美一区| 久草视频中文在线| 亚洲国产天堂久久国产91| 中文字幕不卡三区视频| 日日骚一区二区网站| 韩国欧美国产一区| 久久久久无码国产精品不卡| 亚洲成人激情在线观看| 亚洲私拍视频| 相泽南亚洲一区二区在线播放| 极品美女销魂一区二区三区免费 | 欧美1区2区| 少妇激情一区二区三区视频| 精品美女久久久久久免费| 国产一二三区在线视频| 国产在线观看精品| 欧美午夜在线| 精品无码国产污污污免费网站 | 午夜久久电影网| 邻家有女韩剧在线观看国语| 国产精品私拍pans大尺度在线| 性欧美69xoxoxoxo| 99re这里只有| 欧美日韩一区二区三区在线看| 成人黄色网址| 极品尤物一区二区三区| 日本视频中文字幕一区二区三区| 艳妇荡乳欲伦69影片| 日韩电影大片中文字幕| 四虎国产精品免费久久| 秋霞无码一区二区| 国产精品网站导航| 欧美综合视频在线| 国产精品男女猛烈高潮激情| 欧美精品二区| 貂蝉被到爽流白浆在线观看| 日韩精品一区二区在线观看| 亚洲日本网址| 水蜜桃色314在线观看| 国产精品久久免费看| 五月天婷婷激情网| 91久久久久久久久久|