tags 639277 + moreinfo wontfix
thanks

Axel Beckert wrote:
> If I try to copy a symlink which points to a directory, cp refuses to do
> so without -r despite it copies the symlink itself and not the contents
> with "cp -r", even if the symlink was given on the commandline without
> trailing slash:

Thank you for the bug report.  However I believe this to be correct
behavior.  The magic option isn't -r.  The magic option is -d.

Symlinks violate some principles of least surprise.  Therefore it is
no surprise that it is impossible to make all uses of symlinks
unsurprising.

The cp documentation says:

  `-d'
     Copy symbolic links as symbolic links rather than copying the
     files that they point to, and preserve hard links between source
     files in the copies.  Equivalent to `--no-dereference
     --preserve=links'.

Therefore the intention is that to copy a symlink as a symlink the -d
option should be included.  (Note that -d is included in the -a option.)
The -r documentation is also relevant.

  `-R'
  `-r'
  `--recursive'
     Copy directories recursively.  By default, do not follow symbolic
     links in the source; see the `--archive' (`-a'), `-d',
     `--dereference' (`-L'), `--no-dereference' (`-P'), and `-H'
     options.  Special files are copied by creating a destination file
     of the same type as the source; see the `--copy-contents' option.
     It is not portable to use `-r' to copy symbolic links or special
     files.  On some non-GNU systems, `-r' implies the equivalent of
     `-L' and `--copy-contents' for historical reasons.  Also, it is
     not portable to use `-R' to copy symbolic links unless you also
     specify `-P', as POSIX allows implementations that dereference
     symbolic links by default.

It is documented that use of -r to copy symlinks is not portable.

> /tmp/cp-bugreport → mkdir foo
> /tmp/cp-bugreport → ln -vis foo bar
> `bar' -> `foo'
> /tmp/cp-bugreport → cp -v bar baz
> cp: omitting directory `bar'

Symlinks are by design meant to be completely transparent.  Here the
bar symlink is pointing to a directory.  The cp command by design
isn't looking at it as a symlink (no -d option) but is looking at bar
as being virtually the same as the directory it is pointing to foo.
Because foo is a directory and no recursive option was stated cp is
not copying the directory.  This is correct behavior.

> /tmp/cp-bugreport → cp -rv bar baz
> `bar' -> `baz'

Here cp is given the recursive option and it is arguably inconsistent
that cp copies the symlink as a symlink.  However the behavior in this
context is explicitly documented as being non-portable.  This is for
compatibility with long standing historical practice on other systems
such as SysV systems such as HP-UX where cp -r (and cp -R) copy
symlinks as symlinks.  Doing otherwise in GNU cp would break
compatibility with those legacy systems.

To be clear the reason for this behavior of -r copying a symlink as a
symlink is for compatibility with other systems.  The behavior is
intentional documented behavior.

Since I believe this behavior cannot be changed without introducing
compatibility bugs I have tagged it wontfix.  I have also tagged it
moreinfo to await a response from you.

Bob



--
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