无法保留硬链接。为什么?

无法保留硬链接。为什么?

我正在尝试创建一个可以自动重新制作 Knoppix 发行版的 Makefile。

我正在尝试将文件系统从只读压缩循环设备复制到普通文件系统,以便能够对其进行修改,然后对其进行压缩以替换旧文件系统。这就是 Knoppix 重制的全部内容。我必须保留有关文件系统的所有详细信息,从一个文件系统在另一个文件系统上重新创建硬链接结构。我粘贴的 ls -li 是两个不同文件系统中的同一文件,以显示源具有硬链接,而目标已丢失它们。

$ ls -li */bin/dnsdomainname
   10419 -rwxr-xr-x 4 root root 12992 2010-01-19 10:40 KNOPPIX_V6.2.1CD-2010-01-31-EN.cloop/bin/dnsdomainname
10641687 -rwxr-xr-x 1 root root 12992 2010-01-19 10:40 KNOPPIX_V6.2.1CD-2010-01-31-EN.tree/bin/dnsdomainname

这显然是可能的——如果 rsync 能够保留不同主机之间的硬链接,它应该能够在同一主机上的文件主干之间执行此操作。

由于某种奇怪的原因,使用我所知道的三种方法都无法完成这项工作,我很困惑到底出了什么问题。我花了将近一个工作日来创建脚本,对其进行测试,这似乎是阻止它完全运行的最后一部分。

这些方法是:

sudo nice tar -C $(NAME).cloop -cf - . | sudo nice tar -C $(NAME).tree -xvpf -
sudo cp -av --preserve=all $(NAME).cloop $(NAME).tree
sudo rsync -x -a -H --progress --delete $(NAME).cloop/ $(NAME).tree

我有一个集成的测试套件 ( make changes),其中一部分是计算两个文件系统的 md5sum,差异为空 - 这意味着文件系统之间每个文件的内容完全相同。但是,权限和硬链接号之间的差异表明,每个引用共享(硬链接)inode 的文件现在都是一个单独的 inode,这不是我想要的。这三种方法都做错了同样的事情,这真的很可疑,我没什么主意了。

为了方便您查看,以下是完整的 Makefile:

SITE=ftp://sunsite.icm.edu.pl/pub/Linux/distributions/knoppix/
NAME=KNOPPIX_V6.2.1CD-2010-01-31-EN
PWD=$(shell pwd)

.PHONY: all clean test test-orig

all: $(NAME)-cherry88.iso

$(NAME).iso:
 wget -c -O $(NAME).iso.download $(SITE)/$(NAME).iso && mv $(NAME).iso.download $(NAME).iso

clean:
 if [ ! -z "`mount | grep "$(PWD)/$(NAME).cloop"`" ]; then sudo umount $(NAME).cloop && rm -f $(NAME).cloop.mount || test 1=1; fi
 if [ ! -z "`mount | grep "$(PWD)/$(NAME)"`" ]; then sudo umount $(NAME) && rm -f $(NAME).mount || test 1=1; fi

$(NAME).mount: $(NAME).iso
 mkdir -p $(NAME)
 if [ -z "`mount | grep "$(PWD)/$(NAME)"`" ]; then sudo mount -o loop $(NAME).iso $(NAME); fi
 touch $(NAME).mount

$(NAME).cloop.iso: $(NAME).mount
 nice extract_compressed_fs $(NAME)/KNOPPIX/KNOPPIX - > $(NAME).cloop.iso
 touch $(NAME).cloop.iso

$(NAME).cloop.mount: $(NAME).cloop.iso
 mkdir -p $(NAME).cloop
 if [ -z "`mount | grep "$(PWD)/$(NAME).cloop"`" ]; then sudo mount -o loop $(NAME).cloop.iso $(NAME).cloop; fi
 touch $(NAME).cloop.mount

$(NAME).cdtree.touch: $(NAME).mount
 sudo mkdir -p $(NAME).cdtree
 sudo rm -Rf $(NAME).cdtree
 #sudo nice tar -C $(NAME) --exclude=KNOPPIX/KNOPPIX -cf - . | sudo nice tar -C $(NAME).cdtree -xvpf -
 sudo nice cp -av --preserve=all $(NAME) $(NAME).cdtree
 #sudo rsync -x -a -H --progress --delete $(NAME)/ $(NAME).cdtree
 touch $(NAME).cdtree.touch

$(NAME).tree.touch: $(NAME).cloop.mount
 sudo mkdir -p $(NAME).tree
 sudo rm -Rf $(NAME).tree
 #sudo nice tar -C $(NAME).cloop -cf - . | sudo nice tar -C $(NAME).tree -xvpf -
 sudo cp -av --preserve=all $(NAME).cloop $(NAME).tree
 #sudo rsync -x -a -H --progress --delete $(NAME).cloop/ $(NAME).tree
 touch $(NAME).tree.touch

答案1

使用 cpio 或 tar 等存档格式来保留硬链接。请参阅cpio(1)tar(1)

此外,仅当您使用或 时才cp保留硬链接。-l-a

[编辑] Unix 上的所有工具都通过查看 inode 编号( 输出中的第一个数字ls -li)来检测硬链接。如果编号不同,则没有工具可以重新创建硬链接。

为了解决这个问题,我建议创建 MD5 校验和,对其进行排序,然后过滤重复项 ( uniq -d)。您不必在每个地方都创建校验和,因为大多数硬链接都位于bin目录中。

然后,您可以保留第一个文件并硬链接其余文件。

答案2

使用rsync -a -H

  • -a保留了几乎所有的东西除了硬链接。
  • -H告诉 rsync 保留硬链接。我已经用过很多次了。

查看 rsync 的手册页以获取更多信息。

您也可以使用 tar:

tar --preserve-permissions --preserve-order --check-links -jc /path/to/your/folder /path/to/your/backup_file.tar.bz2

相关内容