Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have directory that contains some symbolic links:

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

I need to copy them to the current directory. The resulting links should be independent from their prototypes and lead directly to their target objects.

  • cp -s creates links to links that is not appropriate behavior.
  • cp -s -L refuses to copy links to directories
  • cp -s -L -r refuses to copy relative links to non-working directory

What should I do?

share|improve this question
    
cp -d made the job on my side. –  m-ric Mar 24 at 17:08
add comment

6 Answers 6

up vote 55 down vote accepted
cp --preserve=links

From the man page:

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

Personally, I use cp -av for most of my heavy copying. That way, I can preserve everything - even recursively - and see the output. Of course, that is just personal preference.

As to why your other options did not do what you expected, -s makes a link instead of copying and -L follows the links in the source to find the file to copy instead of copying the links themselves.

share|improve this answer
4  
+1 much better answer than the accepted one –  Mozza314 Mar 6 '13 at 0:10
2  
You might need to add -R, because otherwise cp will skip directories and symlinks to directories. –  Olivier 'Ölbaum' Scherler Apr 19 '13 at 8:25
2  
I tried this on redhat and it doesn't work –  Mansuro May 27 '13 at 7:57
    
Just what I needed to copy between volumes on an Amazon Linux AMI. Perfect! –  notacouch Jul 22 '13 at 21:50
4  
on a Mac? use cp -a –  Steve Tauber Sep 19 '13 at 17:52
show 1 more comment

If the links contain relative paths, then, copying the link will not adjust the relative path. Use readlink, with the switch -f to follow recursively, in order to get the absolute path of the link. For example:

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

If preserving the relative paths is what you want, than the option -P of cp, as said by Ignacio Vazquez-Abrams, is what you need.

share|improve this answer
add comment

I used the following to duplicate a really large directory. All symbolic links were preserved, the copy was done recursively and I was able to have some visual feedback of the process:

cp -Prv /sourcer_dir/* /target_dir
share|improve this answer
add comment

Try: cp -pr symlink destination

[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]# 

OS - Centos 5 (Linux)

share|improve this answer
add comment

Most of the time, when I need to copy many symbolic links, I'm actually trying to mirror a directory tree. So I want the symlinks and everything else.

This is overkill for copying just a few symlinks, but if you're actually trying to copy an entire tree, this can be very useful:

Use tar.

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

tar doesn't resolve the symlink by default, so symlinks in the mirror copy will point to the same locations as those in the original tree.

This trick makes use of subshells to get the tar command into position at the root of the directory to be mirrored; you can leave one of them out (along with the associated cd command) if you're already in the src or dest directories:

# 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 - )'

Again, this isn't appropriate for every time you want to copy symbolic links, but it is a very useful snippet to know.

share|improve this answer
add comment

Just as the man page says, use -P.

share|improve this answer
2  
on Mac -P does not work on directories so I used cp -a –  Steve Tauber Sep 19 '13 at 17:52
    
Thanks, I've seen and benefited from your answer 3 times now different times over a year. Can't seem to remember it! –  Siddhartha May 1 at 16:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.