用法举例

在这部分当中,我们创建一个简单的两级目录结构,目录中有一个文件, 然后运行简单程序来举例说明 inotify 所能监控的一些事件。 我们将在一个终端会话中启动 inotify 样例程序, 但是因为他是在后台运行的利用 &)因此程序的输出与我们输入的命令会交替出现。 应该在一个终端窗口运行该程序,而在其他窗口输入命令。清单 9 展示了简单文件结构和空文件的创建,以及最初启动该简单程序时的输出。

清单 9. 创建样例环境

  1. ian@attic4:~/inotify-sample$ mkdir -p dir1/dir2  
  2. ian@attic4:~/inotify-sample$ touch dir1/dir2/file1  
  3. ian@attic4:~/inotify-sample$ ./inotify_test dir1/ 
    dir1/dir2/ dir1/dir2/file1&  
  4. [2] 8733  
  5. ian@attic4:~/inotify-sample$   
  6. Watching dir1/ WD=1 
  7. Watching = 1 items  
  8. Watching dir1/dir2/ WD=2 
  9. Watching = 2 items  
  10. Watching dir1/dir2/file1 WD=3 
  11. Watching = 3 items  
  12. ian@attic4:~/inotify-sample$  

在清单 10 当中,展示了列举 dir2 内容时的输出。 第一个事件报告与 dir1 有关,显示出有些东西,名字叫做 dir2 ,在与监控描述符 1 相关的被监控目录当中被打开了。 第二个条目与监控描述符 2 有关,显示出被监控项目在本例中为 dir2 )被打开了。如果正在监控目录树中的多个项目, 可能会经常遇到这种双重输出。

清单 10. 列出 dir2 的内容

  1. ian@attic4:~/inotify-sample$ ls dir1/dir2  
  2. file1  
  3. 4 events queued  
  4. OPEN: Dir "dir2" on WD #1  
  5. OPEN: Dir "(null)" on WD #2  
  6. CLOSE_NOWRITE: Dir "dir2" on WD #1  
  7. CLOSE_NOWRITE: Dir "(null)" on WD #2 

在清单 11 当中,在 file1 中加入一些文字。需要再次强调对于文件以及该文件所在目录的双重打开,关闭,和修改事件。还要注意不是全部事件都会被立刻读取。排队例程被调用了3次,每次有两个事件。如果再次运行该程序,并且每次操作相同,您未必会再次遇到这一特别情况。

清单 11. 在 file1 中加入一些文字

  1. ian@attic4:~/inotify-sample$ echo "Some text" >> dir1/dir2/file1  
  2. 2 events queued  
  3. OPEN: File "file1" on WD #2  
  4. OPEN: File "(null)" on WD #3  
  5. 2 events queued  
  6. MODIFY: File "file1" on WD #2  
  7. MODIFY: File "(null)" on WD #3  
  8. 2 events queued  
  9. CLOSE_WRITE: File "file1" on WD #2  
  10. CLOSE_WRITE: File "(null)" on WD #3 

在清单 12 当中,改变 file1 的属性。我们再次得到有关被监控项目以及其所在目录的双重输出。

清单 12. 改变文件属性

  1. ian@attic4:~/inotify-sample$ chmod a+w dir1/dir2/file1  
  2. 2 events queued  
  3. ATTRIB: File "file1" on WD #2  
  4. ATTRIB: File "(null)" on WD #3 

现在将文件 file1 移动到上一级目录 dir1 当中。在清单 13 中显示了输出结果。 这次没有双重条目。我们实际上得到了 3 个条目,每个目录一个,文件本身一个。 注意 cookie (569) 允许将 MOVED-FROM 事件与 MOVED_TO 事件关联起来。

清单 13. 将文件 file1 移入 dir1

  1. ian@attic4:~/inotify-sample$ mv dir1/dir2/file1 dir1  
  2. 3 events queued  
  3. MOVED_FROM: File "file1" on WD #2. Cookie=569 
  4. MOVED_TO: File "file1" on WD #1. Cookie=569 
  5. MOVE_SELF: File "(null)" on WD #3 

现在创建一个 file1 到 file2 的硬链接。由于到 inode 的链接数量变了,我们得到针对 file1 的 ATTRIB 事件,还得到一个针对 file2 的 CREATE 事件。

清单 14. 创建硬链接

  1. ian@attic4:~/inotify-sample$ ln dir1/file1 dir1/file2  
  2. 2 events queued  
  3. ATTRIB: File "(null)" on WD #3  
  4. CREATE: File "file2" on WD #1 

现在将文件 file1 移入当前目录,将其重命名为 file3 。当前目录没有被监控,因此不存在与 MOVED_FROM 事件相关联的 MOVED_TO 事件。

清单 15. 将 file1 移入不受监控的目录当中

  1. ian@attic4:~/inotify-sample$ mv dir1/file1 ./file3  
  2. 2 events queued  
  3. MOVED_FROM: File "file1" on WD #1. Cookie=572 
  4. MOVE_SELF: File "(null)" on WD #3 

此时,dir2 是空的,因此可以移动它。注意我们得到一个关于监控描述符 2 的 IGNORED 事件,可见我们只在监控两个项目。

清单 16. 移动 dir2

  1. ian@attic4:~/inotify-sample$ rmdir dir1/dir2  
  2. 3 events queued  
  3. DELETE: Dir "dir2" on WD #1  
  4. DELETE_SELF: File "(null)" on WD #2  
  5. IGNORED: WD #2  
  6. Watching = 2 items 

移动文件 file3。注意这次我们没有得到 IGNORED 事件。为什么呢?为什么得到了关于 file 3 的 ATTRIB 事件就是原来的 dir1/dir2/file1)?

清单 17. 删除 file3

  1. ian@attic4:~/inotify-sample$ rm file3  
  2. 1 events queued  
  3. ATTRIB: File "(null)" on WD #3 

记住我们创建了 file1 到 file2 的硬链接。清单 17 显示我们还在通过监控描述符 3 来监控 file2,尽管最开始不存在文件 2!

清单 18. 仍对 file2 进行监控!

  1. ian@attic4:~/inotify-sample$ touch dir1/file2  
  2. 6 events queued  
  3. OPEN: File "file2" on WD #1  
  4. OPEN: File "(null)" on WD #3  
  5. ATTRIB: File "file2" on WD #1  
  6. ATTRIB: File "(null)" on WD #3  
  7. CLOSE_WRITE: File "file2" on WD #1  
  8. CLOSE_WRITE: File "(null)" on WD #3 

现在删除 dir1 来监控事件级联,因为程序它不监控任何事,它结束了自己。

清单 19. 删除 dir1

  1. ian@attic4:~/inotify-sample$ rm -rf dir1  
  2. 8 events queued  
  3. OPEN: Dir "(null)" on WD #1  
  4. ATTRIB: File "(null)" on WD #3  
  5. DELETE_SELF: File "(null)" on WD #3  
  6. IGNORED: WD #3  
  7. Watching = 1 items  
  8. DELETE: File "file2" on WD #1  
  9. CLOSE_NOWRITE: Dir "(null)" on WD #1  
  10. DELETE_SELF: File "(null)" on WD #1  
  11. IGNORED: WD #1  
  12. Watching = 0 items  
  13. Terminating 

inotify 的使用情况

可将 inotify 用于多种目标。下面列举一些可能的情况:

性能监控

您可能想确定应用程序打开最频繁的文件是哪个。如果发现一个小文件被频繁打开与关闭, 您可能会考虑采用内存版,或者改变应用程序来采取其他方式共享该数据。

元信息

您可能想记录文件的附加信息,例如起始创建时间,或者最后改变该文件的用户 id 。

安全

您可能会因为安全原因,需要对特定文件或目录的所有访问进行监控。

我们的样例代码监控所有事件并进行报告。实际上,您可能想依据您的需要,来查看这些事件的特定子集。您可能想监控不同被监控项目的不同事件。例如,您可能想监控文件的打开与关闭事件,但对于目录只想监控创建与删除事件。在任何可能的时候,您可以监控您所感兴趣的最小事件集。

结束语

在应用到性能监控,程序调试,以及自动化等领域时,inotify 是功能强大,高级粒度机制的 Linux 文件系统监控工具。利用本文提供的样例代码,您可以开始编写用来实时记录文件系统事件并最小化性能开销的应用程序。


相关内容