我的电脑上所有内容相同的文件现在都已硬链接。(我的数据已完全删除重复数据。这是我从旧电脑复制数据的方式的结果。)
既然对一个文件执行的某些操作可能会悄悄影响许多其他文件,那么我现在需要注意哪些陷阱?
我知道删除我正在处理的文件不会有问题(假设我是故意删除的)。它不会影响任何其他硬链接文件,而且我认为删除操作不会导致意外的副作用。
移动或重命名文件没有问题。我没有看到任何意外后果。
我不认为复制硬链接文件是个问题,但我对这方面的任何意外后果没有信心。我所看到的是,复制硬链接文件(到同一磁盘)会cp
保持副本的硬链接(即,副本中的 inode 编号不会改变)。复制到另一个文件系统显然会破坏硬链接。(我猜一个陷阱就是忘记这个事实,因为我的电脑有 3 个硬盘。)
更改权限确实会影响所有链接文件。到目前为止,这已被证明很方便。(我将大量硬链接文件设为只读。)
上述操作似乎都不会产生任何重大的意外后果。
但是,正如 Daniel Beck 在评论中向我指出的那样,编辑或修改文件有时会出现问题。这取决于工具,也可能取决于编辑类型。(例如,使用 sed 编辑小型文本文件似乎总是会破坏链接,而使用 nano 则不会。)这就引入了编辑一个文件可能会影响全部硬链接文件(即改变原始的inode)。
我提出的解决方案这样做的目的是使所有硬链接文件都变为只读(而且大多数情况下都是这样)。如果我无法对某些文件执行此操作,我将取消链接这些特定文件。这种只读方法有什么问题吗?
我假设如果我去编辑一个文件并发现它是只读的,我会记得在使它可写的同时取消链接该文件名。因此,一个陷阱可能是忘记这条规则。在这种情况下,我不得不依赖我的备份。
我上述的说法正确吗?我还需要知道什么?
顺便说一句,我正在运行 Kubuntu 12.04。我也在使用 btrfs。(我的 PC 上有 2 个 SSD 和 1 个 HDD。我还将添加一个外部 USB HDD。我还连接到网络并安装了一些 NFS 共享。我不认为这些最后的部分与问题有关,但我还是添加它们以防万一。)
顺便说一句,由于我有多个驱动器(具有单独的文件系统),因此要取消链接任何文件,我只需将其复制到另一个驱动器,然后将其移回。但是,使用 sed 也可以(在我的测试中)。这是我的脚本:
sed -i 's/\(.\)/\1/' file1
令人惊讶的是,这甚至可以取消零字节文件的链接。在我的测试中,它似乎也可以在没有任何特殊选项的情况下处理非文本文件。(但我知道--binary
在 Windows、MS-DOS 和 Cygwin 上可能需要该选项。)但是,复制到另一个磁盘并移回可能是取消链接的最佳方法。对于我的用例,unlink
命令实际上并不是“取消链接”,而是“删除”。
答案1
一个陷阱是文件被覆盖。
有些应用程序会尝试删除文件,并在原有名称下写入新文件。在这种情况下,文件名将被分离。其他应用程序会尝试直接打开文件进行写入。在这种情况下,其他名称的内容也会更改。但是,当您将所有重复的链接文件设为 r/o 时,这很容易区分。
答案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
使用该列表,我可以放心地删除我不想保留的文件名。最终,我可能不再有任何硬链接的照片。
3.我想不出第三个陷阱。如果有人有超过 2 个陷阱,请回答,我会接受你的答案(假设它比我的更好)。
总的来说,如果我将所有硬链接文件设为只读,我认为硬链接不会给我的日常计算任务增加太多复杂性。我可以使用类似以下命令轻松完成此操作:
find . -type f -links +1 -perm /g+w,o+w -iname *.gif -exec chmod 444 '{}' \;
我可以根据需要更改路径或文件扩展名。我不打算触碰 Linux 默认安装使用的任何硬链接。我只处理个人数据中的硬链接。我只需使用一个命令即可将所有硬链接文件更改为只读。
随着时间的推移,我会摆脱不必要的文件名,简化我的数据(和我的生活)。如果文件确实是只读的,并且有必要重复,我会无限期地保留这些文件的硬链接。
但是,在某些情况下,我会故意取消链接文件并留下独立的重复文件。最后一种情况在源代码树中非常常见;相同的文件内容在多个地方是合理的,并且应该是可写的。当我遇到只读的源代码文件并且需要编辑它时,我会取消链接。通常,只需编辑文件即可取消链接。但我可以使用这个命令来确保这一点,我知道它可以取消文件的链接:
sed -i 's/\(.\)/\1/' file1
例子:
以下是上述陷阱 #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