rsync replacing symlinks without warning (resend)

Kevin Korb kmk at sanitarium.net
Sun Feb 4 18:19:30 UTC 2024


rsync's -v is fairly useless.  Learn to use -i instead or in addition to.

On 2/4/24 12:58, Andreas Gruenbacher via rsync wrote:
> Hello,
> 
> when trying to rsync files between hosts, I ran into a surprising case
> in which rsync replaces a symlink with a directory, with no indication
> of any kind.
> 
> In the following reproducer, rsync is called as follows:
> 
>    rsync --verbose --recursive --relative --delete a/./lib/modules b/
> 
> Directory b contains a 'lib' symlink pointing to 'usr/lib', and rsync
> removes that and replaces it with a directory.
> 
> In my real-world use case, this caused '/lib' -> '/usr/lib' symlinks
> to be replaced with '/lib' directories, which left the receiving test
> machines in a fairly sad state.
> 
> I have since figured out that I can get rsync to behave as expected by
> adding the --keep-dirlinks option, but ...
> 
> it's very unfortunate that when rsync does that kind of thing, it
> leaves no indication in the 'rsync --dry-run' and 'rsync -v' output.
> Could that please be fixed?
> 
> Thanks,
> Andreas
> 
> 
> #! /bin/sh
> 
> tmp=$(mktemp -dt ${0##*/}.XXXXXXXXXX)
> trap 'cd /; rm -rf $tmp' EXIT
> cd "$tmp"
> 
> umask 022
> 
> mkdir -p a/lib/modules
> echo foo > a/lib/modules/foo
> 
> mkdir -p b/usr/lib/modules
> ln -s usr/lib b/lib
> 
> show() {
>      find "$@" | xargs stat -c "%F %N" | sort -k2
> }
> 
> echo "from:"
> show a
> 
> echo
> echo "to:"
> show b
> 
> echo
> echo "rsync:"
> rsync \
>      --verbose \
>      --recursive \
>      --relative \
>      --delete \
>      a/./lib/modules \
>      b/
> 
> echo
> echo "to:"
> show b
> 
> # SCRIPT OUTPUT with rsync 3.2.7:
> # ==============================
> =
> # from:
> # directory 'a'
> # directory 'a/lib'
> # directory 'a/lib/modules'
> # regular file 'a/lib/modules/foo'
> #
> # to:
> # directory 'b'
> # directory 'b/usr'
> # directory 'b/usr/lib'
> # directory 'b/usr/lib/modules'
> # symbolic link 'b/lib' -> 'usr/lib'
> #
> # rsync:
> # sending incremental file list
> # lib/
> # lib/modules/
> # lib/modules/foo
> #
> # sent 160 bytes  received 47 bytes  414.00 bytes/sec
> # total size is 4  speedup is 0.02
> #
> # to:
> # directory 'b'
> # directory 'b/lib'
> # directory 'b/lib/modules'
> # directory 'b/usr'
> # directory 'b/usr/lib'
> # directory 'b/usr/lib/modules'
> # regular file 'b/lib/modules/foo'
> 
> 



More information about the rsync mailing list