Pregunta:
Necesito "instalar" un montón de archivos en otro directorio manteniendo intacta la estructura del directorio de los archivos fuente. Por ejemplo, si tengo ./foo/bar/baz.txt
yendo a /var/www/localhost/webroot/
quiero que el resultado sea /var/www/localhost/webroot/foo/bar/baz.txt
. rsync
tiene esta capacidad en --relative
, pero cuando hice esto descubrí que no era amigable con los enlaces simbólicos:
$ ls -ald /var/www/localhost/webroot/ | grep ^l
lrwxrwxrwx 1 www-data www-data 15 2014-01-03 13:45 media -> ../static/media
lrwxrwxrwx 1 root root 13 2014-02-24 13:47 var -> ../static/var
$ rsync -qrR . /var/www/localhost/webroot/
$ ls -ald /var/www/localhost/webroot/ | grep var
drwxr-xr-x 3 root root 4096 2014-02-24 13:52 /var/www/localhost/webroot/var
Entonces verá que el enlace simbólico ya no es un enlace simbólico, ¡los archivos se copiaron en el lugar equivocado!
rsync
también tiene la --no-implied-dirs
, que superficialmente parece hacer lo que quiero, pero solo funciona como pretendo cuando no hago un rsync recursivo, así que tengo que:
find . -type f -print0 | xargs -0I{} rsync -R --no-implied-dirs {} /var/www/localhost/webroot/
¿Hay alguna forma más directa de lograr esta duplicación de archivos sin borrar los directorios intermedios de enlaces simbólicos (con o sin rsync)?
Respuesta:
Utilice la opción de rsync
-K
( --keep-dirlinks
). Desde la página de manual:
-K, --keep-dirlinks
This option causes the receiving side to treat a
symlink to a directory as though it were a real
directory, but only if it matches a real directory from
the sender. Without this option, the receiver’s
symlink would be deleted and replaced with a real
directory.
For example, suppose you transfer a directory foo that
contains a file file, but foo is a symlink to directory
bar on the receiver. Without --keep-dirlinks, the
receiver deletes symlink foo, recreates it as a
directory, and receives the file into the new
directory. With --keep-dirlinks, the receiver keeps
the symlink and file ends up in bar.
One note of caution: if you use --keep-dirlinks, you
must trust all the symlinks in the copy! If it is
possible for an untrusted user to create their own
symlink to any directory, the user could then (on a
subsequent copy) replace the symlink with a real
directory and affect the content of whatever directory
the symlink references. For backup copies, you are
better off using something like a bind mount instead of
a symlink to modify your receiving hierarchy.
See also --copy-dirlinks for an analogous option for
the sending side.