RSYNC no elimina directorios de origen


27

Estoy usando rsync para recuperar archivos esenciales de un servidor, luego elimino los archivos del servidor una vez que los tengo localmente. El comando completo que estoy ejecutando está debajo.

Esto elimina con éxito los archivos en el servidor de origen, sin embargo, todavía quedan directorios vacíos. No recibo ningún mensaje o error. Toda la salida es normal. Quizás esta sea la funcionalidad prevista.

¿Cómo puedo decirle a rsync que limpie todo, incluidos los directorios?

rsync --progress -vrzh --remove-source-files

La versión es 3.0.9 en ambos extremos.


Respuestas:


13

El comportamiento --remove-source-filesque observa es exactamente el especificado por man rsync:

--remove-source-files

   This tells rsync to remove from the sending side the files (meaning non-directories) that are a part of the transfer and have been successfully duplicated on the receiving side.

No hay un comando específico para eliminar los directorios, ya que estas dos discusiones en StackExchange y ServerFault se muestran claramente. La solución sugerida es emitir dos comandos separados:

 rsync -av --ignore-existing --remove-source-files source/ destination/ && \
 rsync -av --delete `mktemp -d`/ source/ 

La última parte del comando sugerido en estas dos publicaciones,

 rmdir source/

que se necesita para eliminar el directorio fuente (ahora vaciado) tiene este formulario en estas publicaciones porque los OP y las respuestas están usando rsync para mover grandes cantidades de archivos dentro de la misma máquina. En su caso, tendrá que hacer esto manualmente.


55
La rsync --deletesugerencia es peligrosa porque ignora la posibilidad de que rsync no se haya completado o que haya nuevos archivos en la fuente. El findsiguiente método de @ slhck es mucho más seguro.
Sai

29

La página de manual incluso dice:

--remove-source-files   sender removes synchronized files (non-dirs)

Si desea eliminar directorios vacíos en su fuente, si aún quedan archivos, haga lo siguiente:

find . -depth -type d -empty -delete

Pero para un directorio raíz vacío, una rm -rf <directory>voluntad será suficiente.


55
Sí, esta es la única solución. es una característica tonta que falta en rsync ... rsync sabe cuándo se procesó el último archivo en un directorio ... también es bastante fácil eliminar el directorio si está vacío.
Erik Aronesty

44
Tenga en cuenta que emitir "rm -rf" es propenso a las condiciones de carrera y lo desaliento.
Raúl Salinas-Monteagudo

Variante que no borra el directorio vacío de nivel superior:find some_dir -depth -type d -empty -not -path some_dir -delete
Cameron Tacklind

5

El uso de " rm -rf " tiene una condición de carrera inherente, es decir, puede eliminar archivos que acaban de crearse entre las invocaciones rsync y rm .

Prefiero usar:

rsync --remove-source-files -a server: entrante / entrante / &&

servidor ssh encuentra entrante -tipo d -delete

Esto NO eliminará los directorios si no están vacíos.


2
El rm -rftambién eliminará los archivos que no fueron transferidos por alguna razón.
Kristian

1
Esta respuesta pierde la -depthopción que indica findprocesar en el orden correcto. Como resultado de este error, los directorios que contienen solo directorios vacíos (posiblemente de forma recursiva) no se eliminarán. La variante de @slhck tiene razón.
Stéphane Gourichon

1

-m, --prune-empty-dirs pode cadenas de directorios vacías de la lista de archivos

--force forzar la eliminación de directorios incluso si no está vacío


1
Eso solo evita que rsync copie directorios vacíos. No elimina directorios vacíos.
Navin

1

Elimine los archivos de origen, luego elimine los directorios para estar seguro.

# given this scenario where you generate folders 2014-01-01 etc.. that have an archive myfile.tar.gz
pushd $(mktemp -d)
mkdir 201{4..6}-{01..12}-{01..31}
for i in $(ls); do; touch $i/myfile.tar.gz;done;
# find and rsync on 10 CPU threads directories that match ./2015-*
find /tmp/tmp.yjDyF1jN70/src -type d -name '2015-*' | \
parallel \
--jobs 10 \
--progress \
--eta \
--round-robin \
rsync \
--hard-links \
--archive --verbose --protect-args \
--remove-source-files \
{} /tmp/tmp.yjDyF1jN70/dest
# now safely remove empty directories only
for i in $(ls /tmp/tmp.yjDyF1jN70/src); do; rmdir /tmp/tmp.yjDyF1jN70/src/$i; done;

Más sobre GNU Paralelo

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.