Cómo hacer que rsync elimine directorios del destino que no están en la lista de origen

Cómo hacer que rsync elimine directorios del destino que no están en la lista de origen

Quiero poder sincronizar archivos de varios directorios a un directorio. Si elimino un directorio de la lista de origen, quiero que ese directorio y todos sus archivos se eliminen del destino.

Aquí hay una muestra rápida:

mkdir dir1
touch dir1/file1
mkdir dir2
touch dir2/file2
mkdir dir3
rsync -a dir1 dir2 dir3

dir3 ahora contiene "dir1/archivo1" y "dir2/archivo2".

Si vuelvo a sincronizar y elimino dir2 de la lista:

rsync -a dir1 dir3

Entonces me gustaría que dir2/file2 y dir2 se eliminen del destino.

La opción --delete para rsync solo maneja eliminaciones entre dir1 y dir3/dir1, por lo que dir2 permanece (incluso si se usa --delete).

Revisé las distintas opciones en la página de manual de rsync y no veo ninguna opción que le indique a rsync que "combine" todas las fuentes y las considere como "un" árbol para que "--delete" funcione. lo que quiero que haga. Sin embargo, estoy bastante seguro de que no soy la primera persona que quiere hacer algo como esto.

¿Ideas?

Respuesta1

Obviamente, la --deletebandera no funciona si sincroniza varios directorios de origen con un directorio de destino. En lugar de sincronizar dir1y, dir2puede dir3sincronizar el contenido del directorio principal de dir1y dir2.

Ejemplo (usando el indicador rsync -ipara ver los cambios):

$ mkdir -p dir12/dir1 dir12/dir2 dir3
$ touch dir12/dir1/file1 dir12/dir2/file2
$ rsync -ai dir12/ dir3
cd+++++++++ dir1/
>f+++++++++ dir1/file1
cd+++++++++ dir2/
>f+++++++++ dir2/file2
# BEFORE: dir1 and dir2 were synced to dir3
$ rm -rf dir12/dir2
$ rsync -ai --delete dir12/ dir3
*deleting   dir2/file2
*deleting   dir2/
.d..t...... ./
# AFTER: dir3/dir2 is gone

Si no tiene un directorio principal común, entonces dir12/dir2podría haber un enlace simbólico que apunte al directorio real. Con la opción -L( --copy-links) en la primera rsyncllamada, obtendría la misma estructura de directorio dir3que dir2el directorio (en lugar de un enlace simbólico). Y después de eliminar el enlace simbólico dir12/dir2y sincronizar nuevamente con --deleteel directorio dir3/dir2desaparecerá como en el ejemplo.

EDITAR:

Jugué un poco y es posible que haya encontrado un truco:

$ mkdir empty dir1 dir2 dir3
$ touch dir1/file1 dir2/file2
$ rsync -ai dir1 dir2 dir3
cd+++++++++ dir1/
>f+++++++++ dir1/file1
cd+++++++++ dir2/
>f+++++++++ dir2/file2
$ rsync -ai --delete empty/ dir1 dir3
*deleting   dir2/file2
*deleting   dir2/
.d..t...... ./

Utilícelo empty/como marcador de posición para todos los directorios que desee eliminar.

información relacionada