cp 覆盖而不覆盖目标的硬链接

cp 覆盖而不覆盖目标的硬链接

假设我有以下设置:

$ cat fileA
textA
$ cat fileB
textB
$ ln fileA myLink
$ cat myLink # as expected
textA

我不明白以下行为:

$ cp fileB fileA
$ cat myLink # expected ?
textB

如果我写的话,我会预料到这个结果ln -s fileA myLink,但不是在这里。

我希望cp在覆盖模式下执行以下操作:

  1. fileB复制硬盘上某处的 内容
  2. 链接fileA到该硬盘地址

但相反,我推断它会执行以下操作:

  1. 按照链接操作fileA
  2. fileB复制该地址的内容

似乎并不适用于mv,它按照我的预期工作。

我的问题:

  1. 这是否在我错过的地方进行了解释man cpor man mvman ln
  2. 这种行为只是巧合吗(假设 if 的fileB大小并不比 更大fileA,或者它可以可靠地用作功能吗?
  3. 这不就打败了硬链接的想法吗?
  4. 有什么方法可以修改该行cp fileB fileA以便下一个cat myLink仍然显示textA

答案1

硬链接不存在“跟随链接” - 创建硬链接只是为同一个文件提供几个不同的名称(在低级别,文件实际上是整数 - “inode”,它们的名称只是为了用户方便) - 有没有“原件”和“副本”——它们是相同的。因此,您打开和写入的硬链接是完全相同的,它们都是相同的。

因此,cp默认情况下会打开一个文件并向其写入内容,从而更改该文件(以及它所具有的所有名称)。所以是的,这是预期的。现在,如果您(而不是重写)首先删除其中一个名称(从而减少链接计数),然后使用与您的名称相同的名称重新创建新文件,那么您最终会得到两个不同的文件。那就是cp --remove-destination要做的事。

1基础知识记录在 link(2)ln(1)

2是的,这是正常行为而不是侥幸。但请参阅上面的评论cp --remove-destination

3不,不是真的。硬链接只是同一文件的几个名称。你似乎想要的是 COW(写时复制)链接,它只存在于特殊的文件系统中

4是的,cp --remove-destination fileB fileA

答案2

是的,这是预期的行为。 ln fileA myLink创建一个硬链接,即 fileA 和 myLink 是同一个磁盘文件的两个名称。

用于ls -il显示索引节点数字,您将看到在示例末尾仅创建了两个不同的文件。

除了您引用的手册页之外,您可能还想阅读man 2 link有关底层系统调用的更多详细信息。


我推断 cp 不仅将 fileA 的链接覆盖为新创建的 fileB 副本的链接,而且实际上遵循 fileA 的链接并在那里写入 fileB 的副本?

你误解了什么是关联是。 cp不“跟随 fileA 的链接”,就像跟随 myLink 的链接一样。两个目录条目都链接到同一个 inode。考虑一下,当您rm访问文件时,底层系统调用被命名为unlink

相关内容