61

Problem

When copying files with cp -H or cp -L, I get the same results:

$ ls -l fileA
  fileA -> fileB
$ cp fileA somewhere/ -H
$ ls -l somewhere/
  fileA     # fileA is a copy of fileB, only renamed, with same properties!

This answer here describes both options as similar UNLESS used in combination with -R. Not for me. Soft- as hardlinked files become renamed copies of the files they point to at the source.
 

Question:

What is the proper use of cp -H and cp -L? Is this the expected behavior?


  My attempt to solve: man cp tells me quite the same for both options, but info cp's wording makes it even more confusing for me. Maybe one can help me break this down a bit:

-H If a command line argument specifies a symbolic link, then copy the file it points to rather than the symbolic link itself. However, copy (preserving its nature) any symbolic link that is encountered via recursive traversal.

This sounds like a contradiction to me: I guess that »a symbolic link's nature« is that it points somewhere…

-L, --dereference Follow symbolic links when copying from them. With this option, cp cannot create a symbolic link. For example, a symlink (to regular file) in the source tree will be copied to a regular file in the destination tree.

I do know that a symlink isn't a regular file, but… I admit I'm overchallenged with this explanation here.

2
  • Run info cp, search for -R. It says Copy directories recursively. But you are testing with non-directories. The difference is about what's inside the directories you are copying, not the command line arguments.
    – Mikel
    Oct 12, 2013 at 4:58
  • @Mikel I've tried with copying the content of directories and copying the directories with content themselves and got quite the same results. Also: I sat quite a long time in front of info cp and tried hard to figure out what the choice of words on this option actually means – and which this posting is about. The posting also contains the actual wording from info cp - thus I must have at least opened it… ;)
    – erch
    Oct 12, 2013 at 12:54

2 Answers 2

81

With symlinks, tools have two things they can do:

  1. Treat the symlink as a symlink ("preserving its nature"), or
  2. Treat the symlink as the type of file that it points to.

Saying that -H "preserves its nature" is not a contradiction. Consider the alternative. If you use -L, any symlinks cp finds will be opened, and their contents copied to the target file name. So the source was a symlink, but its copy is not a symlink. So it "lost its nature as a symlink".

Consider

$ mkdir subdir
$ echo "some contents" > subdir/file
$ ln -s file subdir/link

# definition of "list", the abbreviated ls -l output used below
$ list() { ls -l "$@" | \
    awk '$0 !~ /^total/ { printf "%s %s\t%s %s %s\n", $1, $5, $9, $10, $11 }' ; }

$ list subdir
-rw-rw-r-- 14   file  
lrwxrwxrwx 4    link -> file

$ cp -rH subdir subdir-with-H
$ list subdir-with-H
-rw-rw-r-- 14   file  
lrwxrwxrwx 4    link -> file

$ cp -rL subdir subdir-with-L
$ list subdir-with-L
-rw-rw-r-- 14   file  
-rw-rw-r-- 14   link  
2
  • Great answer—I love the way you illustrate what the options do. It doesn't quite answer my question, which is about copying symlinks to sibling directories, but you've made it obvious how I can do a quick experiment to find out. 😉 Oct 30, 2016 at 21:19
  • 1
    Ah, turns out what I really wanted to know was this: superuser.com/a/138594/219388 Oct 30, 2016 at 21:22
25

The difference in behavior between -L and -H comes when -r is specified as well. cp won't create symlinks in subdirectories with -L -r but it will if you use -H -r.

2
  • 4
    cp: the -H, -L, and -P options may not be specified with the -r option.
    – 3z33etm
    Feb 8, 2019 at 15:17
  • Yes, I think you mean -RH and -RL (capital R), using -r give the same result as if -P were set.
    – will
    May 8 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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