我创建了一个文件的硬链接,如下所示:
ln /path/to/source/file1 /path/to/target/file2
使用 md5sum,两个文件完全相同。过了一会儿,源文件被另一个程序修改了。目标文件没有“更新”。md5sum 现在不同了。当然,这两个文件位于同一个分区上,否则我无法创建链接。
我想要做的是将源文件的副本放入目标文件夹(已版本化),以便我可以在其他地方访问源文件。
我尝试将源文件移动到具有不同名称的目标文件夹,然后在源处创建指向它的符号链接,但是期望该文件的程序随后(以某种方式)在目标文件夹中创建了它想要的名称的文件。
有想法吗?
答案1
我的猜测是版本控制系统(哪一个?)移动/删除硬链接文件并创建一个不再硬链接到原始文件的新副本。
原始文件的链接数(输出中的第一个数字列ls -l
)是多少?如果是 1,则链接丢失。如果是 2,则必须找到真正的第二个副本,也许可以使用 find 命令。为此,请输入以下命令:
find /commonparent_dir -samefile /path/to/original_file
/path/to/original_file
这将从公共父目录(即挂载点)开始搜索与文件具有相同 inode 的文件。
答案2
我可以在测试用例中复制该场景,所以我推测这就是正在发生的事情。如果删除源文件,硬链接就会丢失。即使创建了同名的新文件,硬链接当然也不会恢复。我认为这一定是发生的事情。更新源文件的程序必须删除文件并重新创建它。
答案3
造成此行为的原因是,大多数 POSIX 兼容程序首先将新文件写入临时文件,然后将生成的文件移到现有文件上。这样做是为了避免在断电的情况下丢失文件的新旧版本,直到该过程完成。这种“将文件移到现有文件上”会破坏先前创建的硬链接。
当您拥有硬链接文件并想要在不破坏硬链接的情况下修改原始源数据时,您必须就地覆盖数据,如果在此过程中断电,数据丢失是不可避免的。一些编辑器可以选择这样做,但 POSIX 兼容系统上的大多数文本编辑器使用创建新的临时文件,执行原子移动将临时文件移动到现有文件上,这会产生破坏硬链接的副作用。对于大多数目的而言,破坏硬链接实际上是想要的副作用。
无论你使用什么方法修改文件遵循先创建临时文件并将其移动到包含原始硬链接的文件名的逻辑。您必须使用其他方法来修改该方法以避免破坏硬链接。