符号链接复制目录层次结构

Posted

技术标签:

【中文标题】符号链接复制目录层次结构【英文标题】:symlink-copying a directory hierarchy 【发布时间】:2010-11-17 11:00:51 【问题描述】:

在 Linux 上“复制”目录层次结构以便创建新的目录层次结构而所有“文件”只是指向源层次结构中实际文件的符号链接的最简单方法是什么?

cp -s 不能递归工作。

【问题讨论】:

另见unix.stackexchange.com/q/196537/10047。 【参考方案1】:

我刚刚在一个 linux 机器上进行了快速测试,cp -sR /orig /dest 完全按照您的描述:创建一个目录层次结构,其中包含将非目录的符号链接返回到原始目录。

【讨论】:

它只适用于第一级目录。对于子目录中的每个文件,我得到“xyz-file:只能在当前目录中建立相对符号链接”。 (在 Ubuntu 8.10 上,cp 版本 6.10) 你得到“xyz-file: can make relative symbolic links only in current directory”的原因是因为你为源目录指定了一个相对路径。如果您为源指定绝对路径,它将按您的意愿工作,如下所示:“cp -sR /root/absolute/path/name dest”。 如果您需要/想要使所有符号链接相对,您可以使用symlinks,如下所示:cp -sR /orig /dest && symlinks -rc /dest 不适用于所有系统。在 Mac/PowerPC 上,我得到:cp: illegal option -- s,所以如果你需要制作一个可移植的脚本,你需要一种不同的方法。 只是为了确认这确实符号链接点文件,正如预期的那样。【参考方案2】:
cp -as /root/absolute/path/name dest_dir

会做你想做的事。请注意,源名称必须是绝对路径,不能是相对路径。否则,你会得到这个错误:“xyz-file: can make relative symbolic links only in current directory.”

另外,请注意您要复制的内容:如果 dest_dir 已经存在,您必须执行以下操作:

cp -as /root/absolute/path/name/* dest_dir/
cp -as /root/absolute/path/name/.* dest_dir/

【讨论】:

【参考方案3】:

从原始目录和新目录开始,我认为这对find(1) 命令将满足您的需求:

find original -type d -exec mkdir new/ \;
find original -type f -exec ln -s  new/ \;

第一个实例通过仅查找原始树中的目录并在新树中重新创建它们来设置目录结构。第二个在新树中创建指向原始文件的符号链接。

【讨论】:

这对我来说非常有效(如上所述,cp -as 或 -Rs 在 Mac OS X 上不起作用)。 (cd origParentDir; find origDir .. ; find origDir ..) 可能是一个好主意,以便将相对路径作为 mkdir 和 ln -s 的参数。使用括号启动 (subshel​​l) 因为在子shell中运行 cd 只会临时设置 CWD; CWD 在子shell 退出时恢复。例如。如果您将/src/binutils-2.24“克隆”到$HOME/source,那么您不希望创建“src”文件夹。 奇怪的是ln 没有递归选项...比如ln -s -R orig/dir dest/dir【参考方案4】:

还有“lndir”实用程序(来自 X)可以做这样的事情;我发现这里提到了它:Debian Bug report #301030: can we move lndir to coreutils or debianutils?,我现在正在愉快地使用它。

【讨论】:

我作为原始提问者遇到了确切的问题,在开始编写 shell 脚本后,找到了这个答案并发现 lndir 已经安装。完全按照我的需要工作。【参考方案5】:

我在 Google 上搜索了一下,发现了一个名为 lns 的命令,可以从 here 获得。

【讨论】:

如果带有一些 (2) 选项的 cp 可以解决问题,为什么还要推荐 3rd 方工具。对我来说似乎是一个安全风险。 因为八年前我写答案的时候还不知道 -s 选项。如果您认为答案是好/坏,请随意支持/反对。【参考方案6】:

如果您想弄脏自己的手 这是一个技巧,它将自动递归地创建目标文件夹、子文件夹和符号链接所有文件。

在您要符号链接的文件和子文件夹所在的文件夹中:

    创建一个文件shell.sh:

    nano shell.sh

    复制并粘贴此魔法师:

#!/bin/bash

export DESTINATION=/your/destination/folder/
export TARGET=/your/target/folder/

find . -type d -print0 | xargs -0 bash -c 'for DIR in "$@"; 
do
  echo "$DESTINATION$DIR"
  mkdir -p "$DESTINATION$DIR"        
  done' -


find . -type f -print0 |  xargs -0 bash -c 'for file in "$@"; 
do
  ln -s  "$TARGET$file"  "$DESTINATION$file"
   done' -
    保存文件ctrl+O 关闭文件ctrl+X

    使您的脚本可执行chmod 777 shell.sh

    运行你的脚本./shell.sh

黑客愉快!

【讨论】:

【参考方案7】:

我知道这个问题是关于 shell 的,但是因为你可以从 shell 调用 perl,所以我写了一个工具来做一些与此非常相似的事情,几年前perlmonks 上的posted it。就我而言,我通常希望目录保持链接,直到我另有决定。自动和递归地执行此操作将是一个相当微不足道的更改。

【讨论】:

以上是关于符号链接复制目录层次结构的主要内容,如果未能解决你的问题,请参考以下文章

NTFS 连接与符号链接(用于目录)[关闭]

是否可以让 SCP 在复制过程中忽略符号链接?

linux文件的符号链接

cp命令使用范例

cp:复制文件或目录

NTFS 连接点和符号链接有啥区别?