在Linux中监视文件的更改

3

问题:

在Linux中,有没有办法跟踪文件的进度(例如新文件/保存文件)?

详情:

我知道inotify可以用于跟踪整个文件夹的创建、删除和修改。但是,这些都是非常低级别的操作。文本编辑器通常在保存文件时,会将修改后的缓冲区写入临时位置,然后移动它并覆盖原始文件。这将被inotify视为CREATEMOVE,但我想要的是MODIFY

对我来说,每次保存文件时它都被视为新文件似乎是不合理的。有没有一个可以用来区分新建文件和保存现有文件的标识值?另一种提问方式是:“诸如BeagleSpotlightWindows SearchGoogle Desktop等程序是如何解决这个问题的?”

目标:

这里有一个很好的方式来描述我的需求:使用 Vim,如果我打开一个文件并保存它(:w),那么该文件将被写入临时文件,然后移动到原始文件,欺骗 inotify 认为创建了一个全新的文件,然后用它来覆盖原始文件。但是,如果我使用 svn 添加一个文件,然后使用 Vim 打开并保存该文件(:w),svn 将知道保存的文件实际上是修改过的文件而不是新文件。那么,svn 是如何知道这一点的呢?

2个回答

2

我将尝试解释新建文件和保存文件在Linux中看起来相同的原因。Linux与Windows最大的不同之处在于,inode中没有存储文件创建时间,只有访问时间、修改时间(文件内容更改)和更改时间(inode更改)被存储。因此,除非您将信息保存在其他地方,例如文件本身的元数据中,否则无法确定文件是刚刚创建还是刚刚更改。


即使创建时间被存储了,但在这种情况下,它是否仍会被文本编辑器覆盖?如果文本编辑器像这样保存文件cp a.txt a.txt~; rm a.txt; cp a.txt~ a.txt,会怎样呢?你能想到任何解决方法吗? - puk
临时文件会让事情变得棘手,真相难以辨明。你担心的是安全问题还是其他什么?如果是安全问题,那么像行踪检测这样的程序可能会有所帮助,尽管我不确切地知道它们如何确定文件何时发生变化。 - johnshen64
请看我上面添加的示例。目前安全性不是问题。我正在将文件添加到数据库中,并希望能够知道何时创建了新文件(在这种情况下,我会添加新行),或者当文件保存了100,000次时(在这种情况下,我不想添加100,000个新行)。 - puk
请查看以下链接以获取更多有关我问题核心的信息:https://dev59.com/JmPVa4cB1Zd3GeqP76sz#10544487。 - puk
@johnshen64 读取文件数据不应该是必要的。如果open(2)发送系统范围的信号,文件系统数据根本不会涉及到。 - user877329
显示剩余8条评论

1

johnshen64回答了你为什么看不到它被修改的原因。关于SVN(或Git),它们会将文件识别为已修改,因为它们保留了已管理文件的“密钥”。

因此,对于您的数据库,您需要做同样的事情。例如,您可以使用文件名的简单数字哈希(或文件名本身,但字符串比较很慢)并进行快速查询,以查看文件是否已经被管理,然后再添加它。


你所描述的,检查文件是否已存在于我的数据库中,并不能解决我的问题:区分删除/覆盖文件和通过创建交换文件并用其覆盖原始文件间接编辑现有文件的问题。 - puk
因此,您需要区分具有相同文件名的新文件和已更新文件(使用临时文件进行更新)。我没有从您的问题中得到这一点。您可能需要查看可以附加到ext *文件系统中的可能元数据,这些元数据应该由临时交换在编辑时复制。否则,像SELinux这样的安全系统将无法正常工作! - Huygens
是的!而且,元数据正是我正在寻找的,但我不知道从哪里开始(甚至可能吗?)你最后一句话“或者像SELinux这样的安全系统将无法工作”有点含糊。请您澄清一下。 - puk
关于这个问题,你需要问另一个问题。我知道这是Linux文件系统的一个特性,但我不知道如何使用它。至于SELinux,为了强制执行规则,它会标记文件(使用元数据),而不是像AppArmor一样使用路径名。这意味着如果文件被删除并替换,则标签会丢失,SELinux会检测到,而AppArmor则不会注意到。另一方面,在升级软件时,您需要使用SELinux重新标记文件,但在AppArmor中不需要这样做。例如,请参见:https://www.redhat.com/f/pdf/whitepapers/Filesystem_Labeling_SELinux.pdf - Huygens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接