Would it be possible with rsync to adapt the absolute, symbolic links to a new location at the destination?

Test case
Imagine I have a link pointing to a file like this:

/usera/files/common/links/test_link -> /usera/files/common/test_file

Now I would like to rsync the whole directory common to another location. (group permissions are adapted, look below why)

rsync -av --no-g /usera/files/common/ /userb/common

That gives me:

/userb/common/links/test_link -> /usera/files/common/test_file

The problem
The problem is that the group on the destination is different than on the source (security reasons), so that the test_link does not point to /userb/ space but rather to /usera/ and therefore is not readable for this user.

Would it be possible to tell rsync to adapt the links below the syncing point (/common/ here) to fit to the new destination? That would give a link as such:

/userb/common/links/test_link -> /userb/common/test_file

I tried following the solution to a similar problem, however it does not seem to do what I want..


2 Answers 2


Rsync does not support that. It could be modified to do so but rsync already has too many options. You could accomplish your goal by executing this after the rsync:

find /tmp/userb -type l -ls |
awk '$13 ~ /^\/tmp\/usera/ { sub("/tmp/usera/files/", "/tmp/userb/", $13); print $11, $13 }' |
while read A B; do rm $A; ln -s $B $A; done
  • Thanks a lot.That's a pity, though I do understand that rsync is overloaded. I will try your solution.
    – ronszon
    Jan 20, 2012 at 19:05

Also allowing spaces in either filename (thus using "?" as separator, which at least is a forbidden character in NTFS filesystems):

find /tmp/userb -type l -printf "%p?%l\n" |
awk -vFS="?" '$2 ~ /^\/tmp\/usera/ { sub("/tmp/usera/files/", "/tmp/userb/", $2); print $1 "?" $2 }' |
while IFS=? read A B; do rm "$A"; ln -s "$B" "$A"; done

You must log in to answer this question.

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