为什么硬链接的 inode 不再改变

为什么硬链接的 inode 不再改变

我使用 Vim 8.2 在 Ubuntu 18.04 中编辑文件。当我打开一个文件,进行一些更改并使用 Vim 退出时,该文件的索引节点号将会更改。

据我了解,这是因为我的Vim启用了备份机制,所以每个版本都会创建一个新文件(.swpfile)来替换旧文件。新文件有新的索引节点号。就是这样。

但我发现了一些奇怪的事情。

如下所示,在第一个之后vim 11.cpp,inode 发生了变化,409980变成了409978。然而,在为文件创建硬链接后11.cpp,无论我如何11.cpp用 Vim 修改该文件,它的 inode 号都不会再改变。如果我删除硬链接xxx,它的 inode 号将再次被我的 Vim 的每个版本更改。

这确实让我很困惑。

$ ll -i ./11.cpp
409980 -rw-rw-r-- 1 zyh zyh 504 Dec 22 17:23 ./11.cpp

$ vim 11.cpp     # append a string "abc" to the file 11.cpp
$ ll -i ./11.cpp
409978 -rw-rw-r-- 1 zyh zyh 508 Dec 22 17:25 ./11.cpp

$ vim ./11.cpp   # remove the appended "abc"
$ ll -i ./11.cpp
409980 -rw-rw-r-- 1 zyh zyh 504 Dec 22 17:26 ./11.cpp

$ ln ./11.cpp ./xxx   # create a hard link
$ ll -i ./11.cpp
409980 -rw-rw-r-- 2 zyh zyh 504 Dec 22 17:26 ./11.cpp

$ vim 11.cpp     # append a string "abc" to the file 11.cpp
$ ll -i ./11.cpp
409980 -rw-rw-r-- 2 zyh zyh 508 Dec 22 17:26 ./11.cpp

$ vim 11.cpp     # remove the appended "abc"
$ ll -i ./11.cpp
409980 -rw-rw-r-- 2 zyh zyh 504 Dec 22 17:26 ./11.cpp

答案1

看来设定backupcopyauto:set backupcopy?在 Vim 中运行以确认)。

主要价值观是:

yes制作该文件的副本并覆盖原始文件重命名该文件并 在以前的文件中
no 写入一个新文件,哪种效果最好
auto

[…]

auto值是中间方式:当 Vim 看到可以重命名文件而没有副作用(属性可以传递并且文件不是链接)时使用。当预计出现问题时,将制作一份副本。

如果不清楚:(yes复制并覆盖)不会更改索引节点号,no(重命名并重新写入)会更改它。

就你的情况而言,一开始auto就像是noln ./11.cpp ./xxxVim之后注意到还有另一个链接,auto其工作原理类似yes

答案2

通常,当您启用备份时,最有效的方法是重命名原始文件并使用编辑后的更改创建一个新文件。

但是,当目标文件具有多个硬链接时,这不是正确的做法,因此vim采用效率较低的路线,即写入与原始文件匹配的备份文件,然后就地更新原始文件。

答案3

我重现了一下,然后思考如果inode号改变了会发生什么。

这表明编辑器创建了一个新文件并删除了旧文件。可能需要进行一些重命名以降低数据丢失的风险。如果它对具有多个名称的文件执行此操作,那么当它删除旧名称(打开文件时使用的名称)时,另一个名称将保留,并且仍然指向旧文件。

注意:不存在硬链接之类的东西。只有索引节点指向元数据和文件内容。 (通常)还有一个或多个指向 inode 的文件名。这些名称中的每一个都具有相同的地位(它们都不是硬链接,它们只是指向 inode 的名称)。

相关内容