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