Say I have the following setup :

$ cat fileA
$ cat fileB
$ ln fileA myLink
$ cat myLink # as expected

I do not understand the following behaviour :

$ cp fileB fileA
$ cat myLink # expected ?

I would have expected this outcome if I had written ln -s fileA myLink instead, but not here.

I would have expected cp in overwriting mode to do the following :

  1. Copy the content of fileB somewhere on the hard drive
  2. Link fileA to that hard drive address

but instead, I infer it does the following :

  1. Follow the link fileA
  2. Copy the content of fileB at that address

The same does not seem to go for mv, with whick it works as I expected.

My questions :

  1. Is this explained somewhere that I have missed in man cp or man mv or man ln ?
  2. Is this behaviour just a coincidence, (say if fileB is not much greater in size than fileA), or can it be reliably used as a feature ?
  3. Does this not defeat the idea of hard links ?
  4. Is there some way to modify the line cp fileB fileA so that the next cat myLink still shows textA ?
  • for question 4. , one can do rm fileA && cp fileB fileA to preserve myLink from the change. – marsupilam Aug 14 '16 at 10:04

There is no "following the link" with hardlinks - creating a hardlinks simply gives several different names to the same file (at low level, files are actually integer numbers - "inodes", and they have names just for user convenience)- there is no "original" and "copy" - they are the same. So it is completly the same which of the hardlinks you open and write to, they are all the same.

So cp by defaults opens one the files and writes to it, thus changing the file (and hence all the names it has). So yes, it is expected. Now, if you (instead of rewriting) first removed one of the names (thus reducing link count) and then recreated new file with the same name as you had, you would end up with two different files. That is what cp --remove-destination would do.

1 basics are documented at link(2) pointed to by ln(1)

2 yes it is normal behaviour and not a fluke. But see above remark about cp --remove-destination

3 no, not really. Hardlinks are simply several names for same file. What you seem to want are COW (copy-on-write) links, which only exist is special filesystems

4 yes, cp --remove-destination fileB fileA

  • Thank you. Basically what I expected was that cp worked as cp --remove-destination. I stand corrected. Sorry for the clumsy wording. – marsupilam Aug 14 '16 at 10:21

Yes, this is expected behaviour. ln fileA myLink creates a hard link, that is, fileA and myLink are two names for the same disk file.

Use ls -il to display inode numbers, and you will see that you have only two distinct files created at the end of your example.

In addition to the man pages you referenced, you might also want to read man 2 link for more detail on the underlying system call.

I infer that cp not only overwrites the link of fileA to a link to a newly created copy of fileB, but actually follows the link of fileA and writes a copy of fileB there ?

You are misinterpreting what a link is. cp does not 'follow the link of fileA' any more than it follows the link of myLink. Both directory entries are linked to the same inode. Consider that when you rm a file, the underlying system call is named unlink.

  • Thank you. I now realize that my question is more about cp than about ln. – marsupilam Aug 14 '16 at 10:05

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.