如何使用保留的硬链接复制目录?


40

如何将具有共同文件的目录从一个分区移动到另一个分区?

假设我们已经挂载了分区,/mnt/X并且目录共享带有硬链接的文件。如何将此类目录移动到另一个分区,/mnt/Y保留这些硬链接就可以了。

为了更好地说明,“与硬链接共享文件的目录”是什么意思,下面是一个示例:

# let's create three of directories and files
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
# and copy it with hardlinks
cp -r -l a hardlinks_of_a

更具体地说,我们假设文件的总大小为10G,每个文件有10个硬链接。问题是如何使用10G将其移动到目的地(有人可能会说过使用100G复制它然后运行重复数据删除-这不是我要的内容)

Answers:


29

第一个答案:GNU方式

GNU cp -a递归复制保留尽可能多的结构和元数据。其中包括源目录中文件之间的硬链接。要选择专门保留所有其他功能的硬链接-a,请使用--preserve=links

mkdir src
cd src
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
cp -r -l a hardlinks_of_a
cd ..
cp -a src dst

3
tar上为+ 1,-1为cp使用gnu特定参数。
WhyNotHugo 2012年

您一口气给出了三个答案。您可以将它们分成三部分,以便分别进行评论和评估吗?(提示:您可以编辑此内容,只保留一个-例如“ cp -a”。稍后再添加两个,分别用于“ tar”和“ pax”)
Grzegorz Wierzowiecki 2012年

1
@GrzegorzWierzowiecki拆分完成
艾伦·库里

6
@Hugo:将GNU特定的args用于标准工具没有任何问题。如今,GNU版本已成为事实上的标准,即使未预先安装它们,安装GNU工具也是一种常见的做法(我知道我一直都这样做-它们比solaris和* bsd版本更好) ,并且它们在不同的* nix之间提供了一致性)。指出使用GNUism而不是必需时,可能是一个好习惯。而且Grzegorz也没有说“不在linux上”,因此可以合理地假设这就是他所讨论的环境。
cas

1
@WhyNotHugo:POSIX如何“可能更标准?”。POSIX是使我们成为现实的东西。您是否知道自Windows NT以来的所有Windows版本都完全兼容POSIX?使用POSIX文件I / O功能时,它们的路径长度限制为255个字符,这使它们无用。您是否知道Solaris,Irix,HP-UX都兼容POSIX,但是其工具的所有参数都不相同(例如tar)。cp -a是要替换GNU复制的所有cp版本的最低要求。
Johannes Overmann

36

rsync 为此提供了一个-H--hard-links选项,并具有通常的rsync优点,即可以停止和重新启动,以及可以重新运行以有效处理在上一次运行期间/之后更改的任何文件。

-H, --hard-links
    This tells rsync to look for hard-linked files in
    the source and link together the corresponding
    files on the destination.  Without  this option,
    hard-linked files in the source are treated as
    though they were separate files. [...]

阅读rsync手册页并搜索-H。关于特定的警告有更多的细节。


2
我已经检查-可以。
Grzegorz Wierzowiecki

是的,我知道。我在备份脚本中已经使用了多年。也可以在您的问题中在文件系统之间移动文件。
cas

rsync在建立文件列表时会使用内存块。对我来说,经过数小时的“正在构建文件列表...”,它充满了我16GB的内存,并且没有复制任何内容而获得了保释。YMMV。
msc

2
man rsync从rsync 3.0.0开始,现在使用的递归算法是增量扫描,它使用的内存比以前少得多,并且在完成对前几个目录的扫描之后开始传输。这种增量扫描只会影响我们的递归算法,而不会更改非递归传输。仅当传输的两端至少为3.0.0版时,才有可能。 请注意,请同时将--delete-before--delete-after禁用此改进的算法。
cas

另外,虽然rsync它也是非常有用的工具,但它并不总是适用于所有工作的最佳工具。如今,我更喜欢使用ZFS数据集,以便可以对其进行快照zfs send-我在非ZFS文件系统上大多使用rsync。 btrfs具有类似的快照+发送功能。
cas

14

第三答案:POSIX方式

tar尽管POSIX已标准化tar存档格式,但尚未对该实用程序进行标准化。调用了用于处理tar存档的POSIX实用程序pax,它具有一个额外的功能:能够在单个过程中执行打包和解包操作。

mkdir dst
pax -rw src dst

10

第二个答案:古老的UNIX方式

在源目录中创建tar存档,通过管道发送,然后在目标目录中解压缩。

# create src as before
(cd src;tar cf - .) | (mkdir dst;cd dst;tar xf -)

1
检查->工程。保留硬链接。
Grzegorz Wierzowiecki 2012年

1
关于为什么这实际上会保留硬链接的任何见解?
彼得

1
因为tar保留硬链接。至少在GNU tar中,您可以使用--hard-dereference
cas

就我而言,尝试复制大型目录层次结构(TimeMachine备份),tar保留了一些硬链接,但在某些情况下复制了文件。我认为这是因为tar x尚没有完整的文件列表,因为文件仍从中通过管道传递tar c。如果您在提取存档之前保存了整个存档,那就没关系了。如果有人可以证实这一理论,我将非常高兴。
msc

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.