Rsync complains about symlinks

rsyncsymlink

I'm using the dry-run (-n) option of rsync to compare directories on two different systems. Everything works fine with standard files and directories. However, when I use a directory that includes symbolic links, I get errors:

> ls -l /usr/user1/server10s/system/
total 1
lrwxrwxrwx   1 localuser  other         37 Jun 19 17:18 nrcalc -> /usr/user2/nrcalc10s
> rsync -n -avrc /usr/user1/server10s/* aisdba@Server:deployment_area/server
building file list ... done
system/
cannot delete non-empty directory: system/nrcalc
could not make way for new symlink: system/nrcalc
template/
template/nrcalc
sent 190 bytes  received 24 bytes  38.91 bytes/sec
total size is 330  speedup is 1.54
rsync error: some files could not be transferred (code 23) at main.c(692)

I'm quite happy that it can't delete the directory, as I'm not actually trying to change anything, but why is it even trying to? BTW, I've tried adding both the -l (links) and the -K (copy links) options, with no effect.

How can I get this comparison to work even with symlinks in the directory structure?

Best Answer

As you showed, system/nrcalc is a symlink on the local system, but it's a directory on the remote server. If the directory on the remote system is not empty, rsync will refuse to delete it (to make way for the symlink) unless you specify --force or one of the --delete options. If you don't want to replace the directory on the far end, but you still need to update it with the contents pointed to by the local symlink, you can use --copy-dirlinks.

Rsync complains about this even with --dry-run specified to alert you to the fact that it would need to remove the directory on the far end to do what you're asking it to do. Using any of the options I mentioned in conjunction with -n will give you a clean dry run without actually deleting anything.

As for the other options you tried:

  • The -K option (--keep-dirlinks) is the equivalent of --copy-dirlinks, except on the destination side. Your symlink is on the source side, which is why this option had no effect for you.

  • The -l option (--links) ensures that symlinks are copied as symlinks, but again, without --force or --delete, rsync will refuse to replace a non-empty directory with a symlink. Also, -a implies -l, so you've been using it the whole time anyway.

Related Question