如何复制符号链接?


180

我的目录包含一些符号链接:

user@host:include$ find .. -type l -ls
4737414    0 lrwxrwxrwx   1 user group       13 Dec  9 13:47 ../k0607-lsi6/camac -> ../../include
4737415    0 lrwxrwxrwx   1 user group       14 Dec  9 13:49 ../k0607-lsi6/linux -> ../../../linux
4737417    0 lrwxrwxrwx   1 user group       12 Dec  9 13:57 ../k0607-lsi6/dfc -> ../../../dfc
4737419    0 lrwxrwxrwx   1 user group       17 Dec  9 13:57 ../k0607-lsi6/dfcommon -> ../../../dfcommon
4737420    0 lrwxrwxrwx   1 user group       19 Dec  9 13:57 ../k0607-lsi6/dfcommonxx -> ../../../dfcommonxx
4737421    0 lrwxrwxrwx   1 user group       17 Dec  9 13:57 ../k0607-lsi6/dfcompat -> ../../../dfcompat

我需要将它们复制到当前目录。产生的链接应独立于其原型,并直接指向其目标对象。

  • cp -s 创建指向不合适行为的链接。
  • cp -s -L 拒绝将链接复制到目录
  • cp -s -L -r 拒绝将相对链接复制到非工作目录

我该怎么办?


10
cp -d把工作交给了我。
m-ric

2
cp -R在Mac上
Mirko,2015年

Answers:


201
cp --preserve=links

从手册页:

   --preserve[=ATTR_LIST]
          preserve  the   specified   attributes   (default:   mode,owner-
          ship,timestamps),  if  possible  additional attributes: context,
          links, xattr, all

就我个人而言,cp -av 大部分复印都是我用的。这样,我可以保留所有内容,甚至可以递归保存,并查看输出。当然,那只是个人喜好。

至于为什么其他选项未达到预期效果,则-s创建一个链接而不是复制,并-L按照源中的链接查找要复制的文件,而不是复制链接本身。


3
您可能需要添加-R,因为否则cp会跳过目录和指向目录的符号链接。
Olivier'Ölbaum'Scherler

8
我在redhat上尝试了此方法,但没有用
曼苏罗

41
在Mac上?使用cp -a
Steve Tauber

11
+1为-a选项。嘿,我已经cp无数次地在的联机帮助页中查找了选项,但我一定总是会略过这一页。到目前为止-dpr,我一直在使用,但-a涵盖了所有这些内容,以及其他几个属性的保留。如果我需要这些其他属性,我可能会--preserve再次查找该选项并使用-dr --preserve=all,这就是事实-a!好吧,至少我现在知道– -a完美,这就是我从现在开始将要使用的。
James Haigh 2014年

3
这在Cygwin上不起作用。--preserve=links还不够 它仍然说cp: omitting directory。但是-av有效。
Chloe

44

就像手册页所说的那样,使用-P


8
在Mac -P上无法在目录上运行,所以我使用了cp -a
Steve Tauber

4
谢谢,我一年来有3次见过您的答案,并从中受益。似乎不记得了!
悉达多2014年

这行得通,但是我的手册页说“ -P永远不会在SOURCE中跟随符号链接”,这在直观上与“将符号链接复制为指向目标的符号链接”不同。(“永不遵循”听起来像是与-R结合使用)
RM

cp -P与@kainosnous作品对我的最高投票答案不同。谢谢!
tommy.carstensen

在Redhat上工作。接受的响应不起作用!
Phiber

29

如果链接包含相对路径,则复制链接将不会调整相对路径。readlink与结合使用,以-f进行递归跟踪,以获取链接的绝对路径。例如:

ln -s $(readlink -f old/dir/oldlink) new/dir/newlink

如果保留相对路径是你想要的,不是选择-Pcp,由伊格纳西奥巴斯克斯-艾布拉姆斯为说,是你所需要的。


1
如果您要做的只是将符号链接从相对链接转换为绝对链接,则递归取消引用可能是个坏主意。这里不需要递归,有时存在链接的符号链接是有原因的。符号链接通常用于指定选项或配置选项。例如,在我的系统上,有一个符号链接链/usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-english指定首选的字典。如果要递归地取消引用此链,则产生的符号链接将忽略对该首选项的任何将来更改。
James Haigh 2014年

24

正如一些评论:

cp -a 

效果很好。

从男人那里:

-a    same as -dR --preserve=all

-R    copy directories recursively
-d    same as --no-dereference --preserve=links
--no-dereference   never follow symbolic links in SOURCE

3
...,但前提是没有任何符号链接指向相对路径。
Michael Scheper

11

我使用以下命令来复制一个非常大的目录。所有符号链接均被保留,副本是递归完成的,我能够对该过程进行一些视觉反馈:

cp -Prv /sourcer_dir/* /target_dir

10

大多数时候,当我需要复制许多符号链接时,实际上是在尝试镜像目录树。所以我想要符号链接和其他所有东西。

这对于仅复制几个符号链接来说是多余的,但是如果您实际上是在尝试复制整个树,则这可能非常有用:

使用tar

user@host:/cwd$ ( cd /path/to/src ; tar cf - . ) | ( cd /path/to/dest ; tar xf - )

tar默认情况下不会解析符号链接,因此镜像副本中的符号链接将指向与原始树中相同的位置。

这个技巧利用子外壳使tar命令位于要镜像目录的根目录中。如果您已经在srcdest目录中,则可以忽略其中之一(以及相关的cd命令):

# already in src?
user@host:/src$ tar cf - . | ( cd /path/to/dest ; tar xf - )

# already in dest?
user@host:/dest$ ( cd /path/to/src ; tar cf - . ) | tar xf - 

# just need src/foo?
# this result will be a mirror copy at dest/foo 
user@host:/src$ tar cf - foo | ( cd /path/to/dest ; tar xf - )

# mirror to another system?
user@host:/src$ tar cf - . | ssh user@example.com '( cd /path/to/dest ; tar xf - )'

同样,这并不适合您每次要复制符号链接的情况,但这是一个非常有用的代码段。


1
焦油肯定比我的经验CP更便携
不要亮

4

尝试:cp -pr symlink目标

[root@station1 temp]# ls -l
total 8
-rw-r--r-- 1 root root  0 Jul 27 18:40 abc
lrwxrwxrwx 1 root root 13 Jul 27 18:41 abc.link1 -> /tmp/temp/abc
[root@station1 temp]# cp -rp /tmp/temp/abc.link1 /tmp/temp/abc.link2
[root@station1 temp]# ls -l
total 12
-rw-r--r-- 1 root root  0 Jul 27 18:40 abc
lrwxrwxrwx 1 root root 13 Jul 27 18:41 abc.link1 -> /tmp/temp/abc
lrwxrwxrwx 1 root root 13 Jul 27 18:42 abc.link2 -> /tmp/temp/abc
[root@station1 temp]# 

操作系统-Centos 5(Linux)


3

在Ubuntu上复制目录中的链接和文件时:

cp --no-dereference --preserve=links

5
cp -d是此的简写
hunse

1
我认为无论是cp -acp --preserve=links做多的问题是问。据我了解,这是使用的任何人的正确答案cp,尽管像问题中那样仅使用文件(没有目录),--no-dereference将不会起作用。
palswim

2

使用-P选项,如Ignacio Vazquez-Abrams 上文所述。他没有提到的就是-P没有效果-R。所以你至少需要cp -RP

(该网站尚未允许我发表评论,因此我发布了单独的答案。)


在旧的solaris框上,我的cp不支持-d。cp -rP为我工作;(idk -R和-r之间的差异,-r对我有用)。
spioter

1

cp -s和cp -L是特殊命​​令。根据您的要求,不使用任何内容。

例如,复制目录DIR,其中包含a和指向a的符号链接b。

  • cp -s DIR / * N /创建符号链接而不是复制,N / a-> ../ DIR / a(链接)和N / b->(../ DIR / b)链接到链接
  • cp -L DIR / * N /具有链接解引用的副本,N / a,N / b(与DIR / a相同)

您需要的是N / a(= DIR / a)和N / b-> ../ N / a; 因此,只需使用cp -P选项复制而不取消引用即可。我相信这也是cp的默认设置。

  • -P无引用,保留链接
  • -d将-P选项与-p组合在一起以保留= mode,所有权,时间戳
  • -a结合使用-d选项和-R以递归方式复制目录

请参阅man cpcp --help了解更多选项。

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.