Linux copy files with links

Personally, I use cp -av for most of my heavy copying. That way, I can preserve everything — even recursively — and see the output. Of course, that is just personal preference.

As to why your other options did not do what you expected, -s makes a link instead of copying and -L follows the links in the source to find the file to copy instead of copying the links themselves.

+1 for the -a option. Heh, I’ve looked up options in cp ‘s manpage countless times, yet I must have always skimmed over this one. I have until now been using -dpr , but -a covers all of those, plus the preservation of a couple of other attributes. If I’d have needed these other attributes I would have probably looked up the —preserve option again and used -dr —preserve=all , which is exactly what -a is! Well at least I know now – -a is perfect and this is what I’ll be using from now on.

This didn’t work on Cygwin. —preserve=links wasn’t enough. It still said cp: omitting directory . But -av worked.

Just as the man page says, use -P . This setting says:

-P, --no-dereference never follow symbolic links in SOURCE 

Thanks, I’ve seen and benefited from your answer 3 times now different times over a year. Can’t seem to remember it!

This works, but my man page say «-P never follow symbolic links in SOURCE», which is not intuitively the same as «copy symlinks as symlinks to destination». («never follow» makes it sound like it works in combination with -R)

-a same as -dR --preserve=all -R copy directories recursively -d same as --no-dereference --preserve=links --no-dereference never follow symbolic links in SOURCE 

If the links contain relative paths, then, copying the link will not adjust the relative path. Use readlink , with the switch -f to follow recursively, in order to get the absolute path of the link. For example:

ln -s $(readlink -f old/dir/oldlink) new/dir/newlink 

If preserving the relative paths is what you want, than the option -P of cp , as said by Ignacio Vazquez-Abrams, is what you need.

Читайте также:  Windows start command in linux

It may be a bad idea to dereference recursively if all you are trying to do is to convert symlinks from being relative to absolute. The recursion is not needed here, and sometimes chained symlinks are there for a reason. Symlinks are often used to specify choices or configuration options. For example, on my system there is a symlink chain /usr/share/dict/words -> /etc/dictionaries-common/words -> /usr/share/dict/british-english which specifies the preferred dictionary. If you were to recursively dereference this chain, the resulting symlink would ignore any future changes to this preference.

You may very well not want to modify a relative path. I have cases where there are different versions of a file (that is multiple files with different names), and a symbolic link to the latest version, and all stored in the same directory. Copying the whole directory I want the link unchanged so it still points to the file in its new location.

True, but the OP question explicitely says: > The resulting links should be independent from their prototypes and lead directly to their target objects.

Most of the time, when I need to copy many symbolic links, I’m actually trying to mirror a directory tree. So I want the symlinks and everything else.

This is overkill for copying just a few symlinks, but if you’re actually trying to copy an entire tree, this can be very useful:

user@host:/cwd$ ( cd /path/to/src ; tar cf - . ) | ( cd /path/to/dest ; tar xf - ) 

tar doesn’t resolve the symlink by default, so symlinks in the mirror copy will point to the same locations as those in the original tree.

Читайте также:  Linux set default kernel

This trick makes use of subshells to get the tar command into position at the root of the directory to be mirrored; you can leave one of them out (along with the associated cd command) if you’re already in the src or dest directories:

# already in src? user@host:/src$ tar cf - . | ( cd /path/to/dest ; tar xf - ) # already in dest? user@host:/dest$ ( cd /path/to/src ; tar cf - . ) | tar xf - # just need src/foo? # this result will be a mirror copy at dest/foo user@host:/src$ tar cf - foo | ( cd /path/to/dest ; tar xf - ) # mirror to another system? user@host:/src$ tar cf - . | ssh user@example.com '( cd /path/to/dest ; tar xf - )' 

Again, this isn’t appropriate for every time you want to copy symbolic links, but it is a very useful snippet to know.

Источник

How can I copy a folder that contains symlinks and retain the symlinks in the destination folder? I’m doing something like this with PHP/Bash:

system("cp -r production-clone-target production-sites/"); 

On BSD: cp -PR source destination . On Linux: cp -dr source destination . However, with PHP there are probably much better approaches than running system() (why do you have system() enabled, in the first place?).

3 Answers 3

Try adding the —preserve=links switch to your cp command.

 --preserve[=ATTR_LIST] preserve the specified attributes (default: mode,ownership,timestamps), if possible additional attributes: context, links,xattr, all 

Edit: If under OS X; use cp -a .

@SatoKatsura Huh! Didn’t know that, thanks for the info, just tested under OS X, where the -a switch works. Thought it was the same for all BSD’s.

-l, --links copy symlinks as symlinks 

I like -a , which also includes this one, to copy also sub-directories etc.

-a, --archive archive mode; equals -rlptgoD (no -H,-A,-X) 

So, in your code example you could do this:

system("rsync -a production-clone-target production-sites/"); 

Setting aside the valid concerns about using system() in your PHP program:

Читайте также:  Установка php модуля linux

cp may not have standardized options for doing this that are common to Linux and the BSDs, but pax has.

( cd source && pax -p p -r -w * destination/ )

You must log in to answer this question.

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.13.43531

Linux is a registered trademark of Linus Torvalds. UNIX is a registered trademark of The Open Group.
This site is not affiliated with Linus Torvalds or The Open Group in any way.

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Оцените статью
Adblock
detector