brian m. carlson wrote:
> Package: coreutils
> Version: 7.4-2

Thanks for taking the time to report that.

> If I create a directory structure such as the following:
>
>   a:
>   total 2
>   drwxr-xr-x 2 bmc bmc 1024 2009-06-11 21:06 dir
>   lrwxrwxrwx 1 bmc bmc    4 2009-06-11 21:06 link -> ../b
>
>   a/dir:
>   total 0
>   lrwxrwxrwx 1 bmc bmc 7 2009-06-11 21:06 link -> ../../b
>
>   b:
>   total 2
>   -rw-r--r-- 1 bmc bmc 5 2009-06-11 21:06 file
>
> and then run "cp -aL a/* c", then the copies of file (in c) become hard
> links to each other.  This behavior is not documented, and it does not
> occur if I use -LR instead of -aL.  It appears to be triggered by
> --preserve=links.

That is correct, and deliberate.
With --preserve=links, when cp detects two source files with the
same inode, it must arrange for the corresponding names to be hard
linked in the destination tree.  That is what "preserve=links" means.

The trick is to realize that when you invoke cp with -L,
that tells cp to use stat (which never sees a symlink) rather
than lstat to determine inode numbers.  So those two symlinks
to the same file appear (to cp -L) as hard links, and it preserves
that attribute because you used -a, which includes --preserve=links.

> My opinion is that this behavior is incorrect[0], but I don't care very
> much one way or the other.  If this behavior is intentional, it should
> be clearly documented in the manual page, at the very least.  Either
> changing the behavior or documenting the behavior[1] is satisfactory for
> me.

I reproduced with this:

    $ mkdir c; touch f; ln -s f a; ln -s f b; cp -aL a b c; ls -i1 c
    74161745 a
    74161745 b

> [0] That is, --preserve=links should preserve symlinks as symlinks and
> hard links as hard links.  Just because -L forces all symlinks to be
> dereferenced does not mean that I want to "preserve" symlinks as hard
> links.

--preserve=links preserves *hard* links.
By definition (POSIX), cp -L can never produce a symlink.

> [1] This information should be present in the manual page, not just in
> the info page (which I almost never read).

Sorry, but this corner is obscure enough that any explanation
belongs in the info documentation.
In fact, there are already comments in the texinfo sources
saying that this deserves explanation.

I wrote a few words on -L and added to the --preserve=links description:

    `links'
          Preserve in the destination files any links between
          corresponding source files.  Note that with `-L' or `-H',
          this option can convert symbolic links to hard links.  For
          example,
               $ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c
               74161745 a
               74161745 b
          Note the inputs: `b' is a symlink to regular file `a', yet
          the files in destination directory, `c/', are hard-linked.
          Since `-a' implies `--preserve=links', and since `-H' tells
          `cp' to dereference command line arguments, it sees two files
          with the same inode number, and preserves the perceived hard
          link.

          Here is a similar example that exercises `cp''s `-L' option:
               $ mkdir b c; (cd b; : > a; ln -s a b); cp -aL b c; ls -i1 c/b
               74163295 a
               74163295 b

Here's the patch:

>From 7d350170ae78e1aca68aff81a08116109dd33be5 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyer...@redhat.com>
Date: Mon, 15 Jun 2009 09:10:50 +0200
Subject: [PATCH] doc: cp: describe an oddity of combining -H/-L and 
--preserve=links

* doc/coreutils.texi (cp invocation) [-L]: Elaborate.
[--preserve=links]: Remove comments saying that we need documentation
for just this situation.  Provide more explanation and examples.
Reported by Brian M. Carlson in http://bugs.debian.org/525048.
---
 doc/coreutils.texi |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 155858b..1806295 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -7388,6 +7388,9 @@ cp invocation
 @opindex -L
 @opindex --dereference
 Follow symbolic links when copying from them.
+With this option, @command{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.

 @item -n
 @itemx --no-clobber
@@ -7435,8 +7438,27 @@ cp invocation
 @itemx links
 Preserve in the destination files
 any links between corresponding source files.
-...@c Give examples illustrating how hard links are preserved.
-...@c Also, show how soft links map to hard links with -L and -H.
+Note that with @option{-L} or @option{-H}, this option can convert
+symbolic links to hard links.  For example,
+...@example
+$ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c
+74161745 a
+74161745 b
+...@end example
+...@noindent
+Note the inputs: @file{b} is a symlink to regular file @file{a},
+yet the files in destination directory, @file{c/}, are hard-linked.
+Since @option{-a} implies @option{--preserve=links}, and since @option{-H}
+tells @command{cp} to dereference command line arguments, it sees two files
+with the same inode number, and preserves the perceived hard link.
+
+Here is a similar example that exercises @command{cp}'s @option{-L} option:
+...@smallexample
+$ mkdir b c; (cd b; : > a; ln -s a b); cp -aL b c; ls -i1 c/b
+74163295 a
+74163295 b
+...@end smallexample
+
 @itemx context
 Preserve SELinux security context of the file. @command{cp} will fail
 if the preserving of SELinux security context is not succesful.
--
1.6.3.2.406.gd6a466



-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to