11

It doesn't need to be done by rsync, but it would be nice not have to write a script to do this, and rsync is very close to what I want.

rsync -a (or -l) can preserve symlinks, and -L can dereference symlinks and copy it as if it is normal file/dir. However, is it possible to keep the symlink, and also copy the files/directories the links points to?

Here's an example. Say we have this folder hierarchy:

dirA/link_to_file -> ../dirB/file
dirA/link_to_dir -> ../dirC
dirB/file
dirB/not_this_file
dirC/file
dirC/file2
dirD/others

and when I do rsync -aR dirA dest (or something else), I'd like to have exactly these appear in dest:

dirA/link_to_file -> ../dirB/file
dirA/link_to_dir -> ../dirC
dirB/file
dirC/file
dirC/file2

Is this possible with rsync? Thank you.

Let's assume symlinks having absolute path or pointing to outside the source directory can be ignored.

4
  • 1
    I think your request is underspecified: you require that if dirA/link is a symlink to ../dirB/file, then this should be handled as copying dirB/file to dest/dirB/file and dirA/link to dest/dirA/link. What if dirA/link is a link to ../../another_file? What happens, in general, if dirA/link points to a directory that is higher up in the directory tree? Oct 14, 2010 at 12:05
  • Good catch. In my use case, there's no link point to outside the tree, and there's no absolute path in the links.
    – Wei-Yin
    Oct 14, 2010 at 16:35
  • 1
    The more I think about it, the more I think no standard utility will do this. In the general case, it might need to create a large number of destinations given a single source, if you have a symlink to a symlink or more generally a symlink whose target contains a symlink (e.g. a -> b, b -> c/foo, c -> d/e: a request to copy a should also copy b, c, c/foo, d, d/e and d/e/foo). Oct 14, 2010 at 18:42
  • @Gilles: Yes, you are right. Tracking links could lead to including a lot of files, as long as they are still inside the source directory.
    – Wei-Yin
    Oct 15, 2010 at 11:29

2 Answers 2

2

If you know the symlink name and want to transfer the link and the target you can:

rsync -a 'symlink' .
realdir="$(basename "$(readlink -f 'symlink')")"
rsync -a "$realdir" .

The first rsync transfers just the symlink. The second command finds the real directory name, and the second rsync transfers the directory content.

0

This would be possible if and only if you these were all in 'mydir' and you were to rsync 'mydir' from one place to another. Rsync isn't capable of copying outside of the path you give it (with the exception of following links). e.g

mydir/dirA ...
mydir/dirB ...
...
7
  • Yes, this assumption fit my use case. All the links are inside mydir.
    – Wei-Yin
    Oct 14, 2010 at 16:37
  • @Wei-Yin then simply tell it not to follow symlinks... or have I misunderstood something Oct 14, 2010 at 17:37
  • @xenoterracide: No matter how you invoke rsync, I think it will create a single destination for each source (other than the creation of leading directories). But Wei-Yin wants to create two or more destinations: the link, and its target. Oct 14, 2010 at 18:44
  • apparently I'm confused... Oct 14, 2010 at 20:57
  • @Gilles: there is no need for rsync to follow the symlink, as it will sync the target anyway. So it first copies the symlink, making a dangling symlink. Then it goes on to copy everything else in the directory, including the target of the symlink. Voila, everything fits together nicely. Oct 30, 2010 at 18:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .