如何监视 Linux 上文件和目录的文件系统事件如何监视 Linux 上文件和目录的文件系统事件如何监视 Linux 上文件和目录的文件系统事件如何监视 Linux 上文件和目录的文件系统事件
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

如何监视 Linux 上文件和目录的文件系统事件

Inode notify (inotify) 是一个 Linux 内核子系统,它提供 API 来监视文件系统事件。除了通过适当的编程语言与此类 API 进行通信之外,还可以通过使用一些明确设计的命令行工具(例如 inotifywait)来利用公开的功能,该工具可以轻松安装在所有主要 Linux 发行版中。

在本教程中,我们将了解如何安装和使用 inotifywait 实用程序来监视 Linux 上的文件系统事件。

在本教程中您将学习:

  • 如何在一些最常用的 Linux 发行版上安装 inotifywait

  • 如何使用 inotifywait 监视文件和目录上的文件系统事件

  • 如何监控特定事件

安装

inotifywait 命令行实用程序是 inotify-tools 软件包的一部分,该软件包可在所有主要 Linux 发行版的官方存储库中找到。要在 Fedora 和基于 Fedora 的发行版上安装该软件包,我们运行:

$ sudo dnf install inotify-tools

要在 Debian 及其衍生版本上安装它,我们可以使用以下命令:

$ sudo apt install inotify-tools

该软件包还可以在“Extra”Archilinux 存储库中找到。我们可以使用 pacman 包管理器来执行安装:

$ sudo pacman -Sy inotify-tools

监控文件系统事件

inotifywait 实用程序可用于等待文件系统事件并对其做出反应。在最简单的用法中,我们调用该实用程序并传递我们想要监视的文件或目录的路径作为参数。在下面的示例中,我们以 ~/.bash_profile 文件为例:

$ inotifywait ~/.bash_profile
Setting up watches.
Watches established.

当按照我们上面的方式执行时,该工具会在指定文件上建立一个监视,并在第一个事件发生时存在。举个例子,让我们尝试读取文件的内容:

$ cat ~/.bash_profile

一旦我们从另一个终端窗口启动命令,我们就会收到“OPEN”事件的通知,并且 inotify 退出:

/home/doc/.bash_profile OPEN

如果我们将目录路径作为参数传递给命令,则将监视该目录内的所有文件;但是,不是子目录的内容,因为默认情况下该命令不是递归的。要更改此行为并监视整个目录树,我们所要做的就是使用 -r (--recursive) 选项。以这种方式运行实用程序时,我们可能必须增加允许的监视的最大数量,这可以通过将适当的值写入 /proc/sys/fs/inotify/max_user_watches 文件来完成。但请注意,重新启动时不会保留对文件的更改。查看本教程以了解如何使它们永久化。

监听特定事件

在某些情况下,我们可能希望仅在文件上发生某些特定事件时收到通知。在这种情况下,我们可以简单地使用 -e (--event 的缩写)选项,并将受支持的事件之一作为参数传递。继续前面的示例,要仅监视 ~/.bash_profile 文件上的“修改”事件,我们将运行:

$ inotifywait -e modify ~/.bash_profile

由于我们只监听“修改”事件,因此如果我们读取文件的内容,该命令将继续运行,但一旦我们尝试写入文件,该命令就会通知我们,就像简单地附加一些内容时一样:

$ echo "# This is just a comment" >> ~/.bash_profile

该事件按预期通知:

/home/doc/.bash_profile MODIFY

我们可以监听的事件如下表所示,如实用程序手册中所述。下面列出了事件并给出了它们的描述。

access
读取监视文件或监视目录中的文件。
modify
已写入监视文件或监视目录中的文件。
attrib
监视的文件或监视的目录中的文件的元数据被修改。这包括时间戳、文件权限、扩展属性等。
close_write
监视的文件或监视目录中的文件在以可写模式打开后被关闭。这并不一定意味着该文件已被写入。
close_nowrite
监视的文件或监视目录中的文件在以只读模式打开后被关闭。
close
监视的文件或监视目录中的文件被关闭,无论它是如何打开的。请注意,这实际上是通过监听 close_write 和 close_nowrite 来实现的,因此收到的所有关闭事件都将作为其中之一输出,而不是 CLOSE。
open
打开了监视的文件或监视目录中的文件。
moved_to
文件或目录已移至监视目录中。即使文件只是从同一目录移动到同一目录,也会发生此事件。
moved_from
文件或目录已从监视目录中移出。即使文件只是从同一目录移动到同一目录,也会发生此事件。
move
文件或目录已从监视目录移出或移至监视目录。请注意,这实际上是通过侦听 moving_to 和 moving_from 来实现的,因此收到的所有关闭事件都将作为其中之一或两者输出,而不是 MOVE。
move_self
监视的文件或目录已移动。在此事件之后,将不再监视该文件或目录。
create
在监视的目录中创建了文件或目录。
delete
监视目录中的文件或目录已被删除。
delete_self
监视的文件或目录被删除。在此事件之后,将不再监视文件或目录。请注意,即使没有显式侦听此事件,也可能会发生该事件。
unmount
监视的文件或目录所在的文件系统已卸载。在此事件之后,将不再监视文件或目录。请注意,即使没有显式侦听此事件,也可能会发生该事件。

以“监听”模式收听

在前面的示例中,我们看到默认情况下,一旦发生受监视的事件之一,使用 inotifywait 建立的监视就会立即存在。 如果我们希望命令继续监听事件,我们可以简单地使用-m选项,它是--monitor的缩写形式。

在下面的示例中,我们以监视模式对目标文件建立一个监视,然后,我们首先读取其内容,然后向其附加一些内容。每个操作涉及三个事件,所有这些事件都会被记录:

$ inotifywait -m ~/.bash_profile
Setting up watches.
Watches established.
/home/doc/.bash_profile OPEN                # The file is opened
/home/doc/.bash_profile ACCESS              # The file is read          
/home/doc/.bash_profile CLOSE_NOWRITE,CLOSE # The file is closed after being opened in read-only mode
/home/doc/.bash_profile OPEN                # The file is opened
/home/doc/.bash_profile MODIFY              # The file is modified (we appended content to it)
/home/doc/.bash_profile CLOSE_WRITE,CLOSE   # The file is closed after being opened in writable mode

将文件排除在监视之外

正如我们已经说过的,inotifywait 实用程序可用于侦听指定目录内的文件或整个目录树上的事件。在这种情况下,我们可能希望避免监视特定文件,或明确包含其中的一些文件。为了完成此类任务,我们可以分别使用 --exclude 和 --include 选项。它们都采用 POSIX 正则表达式作为参数。

在下面的示例中,我们监控 ~/.config 目录下的所有文件,除了那些带有“.xml”扩展名的文件:

$ inotifywait -m ~/.config --exclude ".*.xml"

--include 和 --exclude 选项在区分大小写的模式下匹配传递的表达式;然而,两者都有一个在不区分大小写模式下工作的变体:分别是--includei和--excludei。

结论

在本教程中,我们学习了如何在一些最常用的 Linux 发行版上安装 inotify-tools 软件包,以及如何使用 inotifywait 命令行实用程序来监视文件和目录上发生的事件。

©2015-2025 艾丽卡 support@alaica.com