我的台式电脑上的硬链接文件有哪些陷阱?

Mou*_*inX 5 linux filesystems hardlink

我电脑上所有内容相同的文件现在都是硬链接的。(我的数据已完全去重。这是我从旧计算机复制数据的方式的结果。)

现在我需要注意哪些陷阱,对一个文件的某些操作可能会默默地影响许多其他文件?

我知道删除我正在处理的文件不是问题(假设我是故意删除的)。它不会影响任何其他硬链接文件,而且我认为删除操作不会导致意外的副作用。

移动或重命名文件不是问题。我没有看到任何意外的后果。

我不认为复制硬链接文件是一个问题,但我对这方面的任何意外后果没有信心。我所看到的是,制作硬链接文件的副本(到同一磁盘)并cp保持副本硬链接(即,副本中的 inode 编号不会更改)。复制到另一个文件系统显然会破坏硬链接。(鉴于我的 PC 有 3 个硬盘,我想一个陷阱是忘记了这一事实。)

更改权限确实会影响所有链接的文件。到目前为止,这已经证明很方便。(我将大量硬链接文件设为只读。)

上述操作似乎都没有产生任何重大的意外后果。

但是,正如 Daniel Beck 在评论中向我指出的那样,编辑或修改文件有时可能是一个问题。这取决于工具,也可能取决于编辑类型。(例如,使用 sed 编辑小文本文件似乎总是会断开链接,而使用 nano 则不会。)这引入了编辑一个文件可能会影响所有硬链接文件(即更改原始 inode)的可能性。

对此提出的解决方案是将所有硬链接文件设为只读(这已经是大多数情况了)。如果我不能对某些文件执行此操作,我将取消链接这些特定文件。这种只读方法有什么问题吗?

我假设如果我去编辑一个文件并发现它是只读的,我会记得在使其可写的同时取消该文件名的链接。所以一个陷阱可能是忘记了这条规则。在这种情况下,我将不得不依赖我的备份。

我在上述陈述中是否正确?我还需要知道什么?

顺便说一句,我正在运行 Kubuntu 12.04。我也在使用 btrfs。(我在 PC 中有 2 个 SSD 和 1 个 HDD。我还将添加一个外部 USB HDD。我还连接到网络并安装了一些 NFS 共享。我不认为这些最后一点与问题,但我添加它们以防万一。)

顺便说一句,由于我有多个驱动器(带有单独的文件系统),要取消链接任何文件,我要做的就是将其复制到另一个驱动器,然后将其移回。但是,使用 sed 也有效(在我的测试中)。这是我的脚本:

sed -i 's/\(.\)/\1/' file1
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,这甚至取消了零字节文件的链接。在我的测试中,它似乎也适用于没有任何特殊选项的非文本文件。(但我知道--binary在 Windows、MS-DOS 和 Cygwin 上可能需要该选项。)但是,复制到另一个磁盘并移回可能是取消链接的最佳方法。对于我的用例,unlink命令并没有真正“取消链接”,而是“删除”。

Mou*_*inX 2

以下是我到目前为止想到的陷阱:

1.在编辑文件 y 时,可能会无意中更改一个或多个文件 x 的内容。

正如我最初的问题中所述,解决此问题的方法是默认设置所有硬链接文件为只读。对于经常编辑的文件,我根本不会使用硬链接,因为它们可能不合适。

重要更新:这是一个真正的陷阱。有时,编辑者会默默地覆盖文件,即使它是只读的。例如,我有一个权限为 400 并由 root 拥有的空文件。我在 nano 中打开该文件,对其进行编辑并保存。nano 并没有抱怨它是只读的。所有硬链接的电影名现在都有错误的内容。不幸的是,将文件设置为只读并不是我期望的解决方法,这确实是一个严重的陷阱。

2.可能会无意中创建文件的新副本。这本质上与第一个陷阱相反。单个文件内容可以有N个文件名。编辑这些文件名之一现在可能会导致两个不同的内容项,其中 N(文件名数量)根本不会改变。我可能不知道发生了这种情况(如果我不注意硬链接)。

我的例子就是我杂乱无章的照片集。我目前将同一张照片以不同的名称存储在不同的目录中(例如,因为多次从我的相机下载它而没有花时间组织我的照片)。硬链接意味着我不再因此而浪费大量空间。我希望编辑这些文件之一总是会影响所有硬链接文件名(除非我专门将编辑后的照片保存在新名称下)。然而,情况很可能并非如此。因此,陷阱是编辑照片可能会导致我的照片集更加混乱。同样的陷阱也可能适用于音乐或视频(或虚拟机图像等)。

同样的解决方法是我想出的唯一方法——将文件设置为只读,因此在需要编辑时提醒我应该注意硬链接。(是否有更好的解决方法,例如快速重新链接所有文件名的方法?)

我的照片集被硬链接的另一个(积极的)结果是我现在可以更快地组织它。例如,使用此命令我可以找到所有重复的照片:

find 2>/dev/null /home/me/Pictures -type f -links +1 -printf "%n\t%i\t%d\t%s\t%t\t%p\n" | sort -gr > /home/me/Pictures/duplicatesList.txt
Run Code Online (Sandbox Code Playgroud)

使用该列表,我可以放心地删除我不想保留的文件名。最终,我可能不再有任何硬链接的照片。

3.我想不出第三个陷阱。如果有人有两个以上的陷阱,请回答,我会接受你的答案(假设它比我的更好)。

总的来说,如果我将所有硬链接文件设为只读,我认为硬链接不会给我的日常计算任务增加太多复杂性。我可以使用类似于以下的命令轻松完成此操作:

find . -type f -links +1 -perm /g+w,o+w -iname *.gif -exec chmod 444 '{}' \;
Run Code Online (Sandbox Code Playgroud)

我可以根据需要更改路径或文件扩展名。我不打算触及 Linux 默认安装使用的任何硬链接。我只使用个人数据中的硬链接。我可以简单地使用一个命令将所有硬链接文件更改为只读。

随着时间的推移,我将摆脱不需要的文件名并简化我的数据(和我的生活)。如果文件确实是只读的并且需要重复,我将无限期地保留这些文件的硬链接。

但是,在某些情况下,我会取消文件链接并故意留下独立的重复文件。最后一种情况在源代码树中非常常见;相同的文件内容在多个地方都是合理的,并且它应该是可写的。当我遇到只读源代码文件并且需要编辑它时,我会取消链接。通常,只需编辑文件即可取消链接。但我可以通过使用此命令来确定,我知道该命令会取消链接文件:

sed -i 's/\(.\)/\1/' file1
Run Code Online (Sandbox Code Playgroud)

例子:

这是上面的陷阱 #1 的一个例子。这是我刚刚遇到的文件系统中的一个实际示例。

我打算破坏性地编辑“index.html 的副本”,因为我看到了文件“index.original.html”,并且我认为编辑该副本是安全的。然而,事实证明这些文件是硬链接的,因此编辑“副本”也会改变原始文件。

这是显示文件被硬链接的信息:

2   45214   6   6641    Thu Oct 30 10:46:00.0000000000 2008 /Site/FusionAppsVPS/index.original.html
2   45214   6   6641    Thu Oct 30 10:46:00.0000000000 2008 /Site/FusionAppsVPS/Copy of index.html
Run Code Online (Sandbox Code Playgroud)