使用rdfind
我发现了很多硬链接文件(~60-90),我想取消所有它们的链接。一种可能的解决方案是找到所有文件-link +1
并复制它们,删除它们并将其移回链接名称。
有没有更好的解决方案?有没有更简单的方法可以做到这一点?
答案1
你可以做:
find . -type f -links +1 -exec sh -c '
{ rm -f "$1" && cat > "$1"; } < "$1"' sh {} \;
但这不会保留文件元数据。在 Linux 上,你可以这样做:
find . -type f -links +1 -exec sh -c '
{ rm -f "$1" && cp -p /proc/self/fd/0 "$1"; } < "$1"' sh {} \;
请注意,如果cat
或失败(例如磁盘已满),您将丢失/无法复制的cp
文件内容。cat
cp
我们使用-exec {} \;
代替-exec {} +
,以便在找到文件后更新文件的链接计数,这样find
就不会寻找如果链接计数已降至 1,则为最后一个链接(这意味着对于初始链接计数为 4 的文件,只有 3 个实例将被覆盖)。
使用 GNU tar
,您还可以执行以下操作:
find . -type f -links +1 -print0 |
tar --hard-dereference --null -T - -cf - | tar xpf -
这将运行更少的命令,但覆盖更多的文件。
您可能会看到一些:
tar: ./file: file changed as we read it
对于大文件,但这没关系,因为第二种方法tar
会在覆盖文件之前取消链接文件,因此实际上,这与第一种方法非常相似。当第二个 tar 取消链接文件时,这只是第一次tar
注意到链接计数减少(并且 ctime 因此改变)。