From: jellybean stonerfish on
On Fri, 19 Feb 2010 17:14:46 +0100, TP wrote:

> jellybean stonerfish wrote:
>
>>> #########
>>> #!/bin/sh
>>> alias ls='ls --color=auto'
>>> mkdir test_hardlink
>>> cd test_hardlink
>>> touch foo
>>> ln foo bar
>>> ls -l
>>> cp foo not_a_hard_link
>>> ls -l
>>> cp -d foo not_a_hard_link2
>>> ls -l
>>> cp -av --preserve=all foo not_a_hard_link3

This will copy foo, and put it into not_a_hard_link3. If you also
had bar in the command, then foo and bar would be copied into
not_a_hard_link3 preserving the link between them. This doesn't make
links to the source files. Use ln to make a new link to a file.

>>
>> Maybe I don't fully understand you?
>
> Ok! Thanks.
>
> 1/ cp -a preserves all hard links in a directory when copying this
> directory recursively (-a includes "R" option, in fact -a is "-dR
> --preserve=all" according to the manual page).
>
> 2/ But cp -a does not work to copy a single hard link (as I have tried
> in my example).

Because you are copying a single file. If you want to preserve hard
links, you must copy the linked files also, otherwise there is no link
to preserve. It doesn't make any sense to use cp to create a hard link
to a single file. That is what ln is for.

>
> In fact I do not need this feature, but by curiosity: why is it possible
> to preserve a hard link in the first case, but not in the second?

I think I understand your confusion, let's see if I can clear it up.

js(a)blackbox:~$ mkdir hardtest
js(a)blackbox:~$ cd hardtest/
js(a)blackbox:~/hardtest$ ls
js(a)blackbox:~/hardtest$ touch foo
js(a)blackbox:~/hardtest$ ln foo bar

Now hardtest has two files, foo and bar, that are hard linked.
Then I make a directory hardtestcp and put a copy of the files
from hardtest into it with cp -a

js(a)blackbox:~/hardtest$ cd ..
js(a)blackbox:~$ mkdir hardtestcp
js(a)blackbox:~$ cp -av hardtest/* hardtestcp/
`hardtest/bar' -> `hardtestcp/bar'
`hardtest/foo' -> `hardtestcp/foo'

The copy seemed to work. Lets go to the hardtestcp folder and see
if the files in it, foo and bar, are linked to each other.

js(a)blackbox:~$ cd hardtestcp/
js(a)blackbox:~/hardtestcp$ echo "data in" > foo
js(a)blackbox:~/hardtestcp$ cat bar
data in
js(a)blackbox:~/hardtestcp$ cat foo
data in
js(a)blackbox:~/hardtestcp$

Yes they are.

Do you want the files in hardtestcp to be hard linked to the files in
hardtest? If that is the case, then you should use ln not cp.

If you use copy you make a copy of the files you specify on the command
line, not a copy of all hard links to files on the command line. If the
files on the command line happen to be hard links, and you use -a then the
fact that they are links is copied also. If you don't use -a then they
files are copied as normal.

js(a)blackbox:~$ mkdir hardtestcp2
js(a)blackbox:~$ cp -v hardtest/* hardtestcp2/
`hardtest/bar' -> `hardtestcp2/bar'
`hardtest/foo' -> `hardtestcp2/foo'

Notice the output looks the same as the cp -av command above. But the
files are copied without preserving their link status.

js(a)blackbox:~$ cd hardtestcp2/
js(a)blackbox:~/hardtestcp2$ echo "data in" > foo
js(a)blackbox:~/hardtestcp2$ cat foo
data in
js(a)blackbox:~/hardtestcp2$ cat bar
js(a)blackbox:~/hardtestcp2$


From: Kaz Kylheku on
On 2010-02-19, TP <TP(a)frenoespam.fr.invalid> wrote:
> jellybean stonerfish wrote:
>
>>> #########
>>> #!/bin/sh
>>> alias ls='ls --color=auto'
>>> mkdir test_hardlink
>>> cd test_hardlink
>>> touch foo
>>> ln foo bar
>>> ls -l
>>> cp foo not_a_hard_link
>>> ls -l
>>> cp -d foo not_a_hard_link2
>>> ls -l
>>> cp -av --preserve=all foo not_a_hard_link3 ls -l
>>
>> Maybe I don't fully understand you?
>
> Ok! Thanks.
>
> 1/ cp -a preserves all hard links in a directory when copying this directory
> recursively (-a includes "R" option, in fact -a is "-dR --preserve=all"
> according to the manual page).
>
> 2/ But cp -a does not work to copy a single hard link (as I have tried in my
> example).

That would be terrible behavior; to copy a single hard link means in
fact not to copy anything, but only to create a new name for it.

Users of GNU cp rely on ``cp -a X Y'' to make Y a copy of of X (at
least when Y does not name an existing directory) such that the copy Y
preserves the internal structure of X, not such that Y preserves the
identity of X!

> In fact I do not need this feature, but by curiosity: why is it possible to
> preserve a hard link in the first case, but not in the second?

Note that in the first case, cp is still making copies of the objects in
the source tree; it is not making hard links within the new directory
tree which point to the same objects that are in the old directory tree.

Preserving the internal link structure of an object is not the same
thing as simulating the copy of an object by linking.
From: TP on
jellybean stonerfish wrote:

> I think I understand your confusion, let's see if I can clear it up.

Thanks a lot! Now I understand the meaning of "-a"!

Julien


From: TP on
Kaz Kylheku wrote:

>> When using "cp", the hard links are not preserved.
>
> That's because you didn't RTFM.

Yes, I did, but cp -l makes hard links for all files. I just wanted to copy
hard links when they are already hard links. Jellybean Stonerfish has
finally made me understand my confusion.

Thanks a lot!

From: Kaz Kylheku on
On 2010-02-19, TP <TP(a)frenoespam.fr.invalid> wrote:
> Kaz Kylheku wrote:
>
>>> When using "cp", the hard links are not preserved.
>>
>> That's because you didn't RTFM.
>
> Yes, I did, but cp -l makes hard links for all files. I just wanted to copy
> hard links when they are already hard links.

A hard link isn't special kind of object; it's the association between a
directory entry and an object. I.e. it's part of the plumbing.
All files are entered into the directory structure by means of hard
links.