La opción Rsync --delete no elimina archivos en el directorio de destino

14

Estoy tratando de usar la --deleteopción rsyncpara eliminar archivos en el directorio de destino que no está presente en el directorio original

Aquí está el comando que estoy usando:

rsync -avz --ignore-existing --recursive --delete /var/www/* root@mydomaintest.com:/var/www

Entonces mi pregunta es, ¿cómo puedo eliminar todos los archivos en el directorio de destino que no están presentes en el directorio original?

usuario2028856
fuente

Respuestas:

14

Usa este comando:

rsync --archive --verbose --compress --ignore-existing --delete /var/www/ root@mydomaintest.com:/var/www

No necesita un "*" y tampoco debe usarlo.

Para excluir / incluir archivos o directorios, debe usar estos parámetros:

--exclude 'to_exclude*'
--include 'to_include*'
AB
fuente
Bien, déjenme probar esto :)
user2028856
2
Entonces, ¿el "*" que está causando que el comando --delete no funcione?
user2028856
2
Así es como se ve. :)
AB
3
--recursivees sobreabundante porque la opción -aya lo incluye
Temak
1
El "*" podría ser importante en algunos casos porque excluye archivos / directorios que comienzan con ".". Por ejemplo, lo uso cuando uso rsync para copiar un directorio mantenido bajo git desde una máquina de desarrollo a una máquina de producción. No quiero sincronizar el directorio del repositorio .git, o archivos como .gitignore, solo el árbol de trabajo, incluidos los archivos de nivel superior y los subdirectorios.
hollín
14

Su comando no funcionaba porque cuando lo usaba /var/www/*como fuente, su shell realizaba un bloqueo global, es decir, la shell se expandía *a todos los archivos en ese directorio y copiaba los archivos uno por uno, por lo que aquí los archivos individuales se han convertido en las fuentes en lugar de el directorio padre

Entonces, si lo usa /var/www/*, entonces no necesita la --recursiveopción, ya que *hará que los archivos se copien (junto con cualquier directorio con su contenido), no el directorio principal que contiene los archivos. Debido a la misma razón --deleteno funciona, ya --deleteque eliminará los archivos del directorio de destino que no están en el directorio de origen , pero está copiando archivos para que no se eliminen los archivos (se espera).

Esto te hará más claro:

/foo$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test


/bar$ ls -l
-rw-rw-r-- 1 user user 0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user 0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user 0 Apr 16 17:56 spam


$ rsync -avz --ignore-existing --recursive --delete 
/foo/* /bar/

+ rsync -avz --ignore-existing --recursive --delete 
/foo/egg /foo/spam /foo/test /bar/

sending incremental file list
test/
test/hello

sent 173 bytes  received 39 bytes  424.00 bytes/sec
total size is 0  speedup is 0.00


/bar$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test

Como puede ver, he usado la fuente, /foo/*por lo tanto, el rsynccomando que se ejecuta es

rsync -avz --ignore-existing --recursive --delete /foo/egg 
/foo/spam /foo/test /bar/

con *hacer shell para expandirlo y crear todos los archivos individualmente como argumentos de origen, no el directorio padre en su conjunto (y tampoco es necesario --recursiveen este caso).

Entonces, si quieres hacer el --deletetrabajo, ejecútalo como:

rsync -avz --ignore-existing --recursive --delete 
/var/www/ root@mydomaintest.com:/var/www/
heemayl
fuente
44
Excelente explicación que señala el problema real: usar '*' para expandir la lista de fuentes.
Antonio Bardazzi
Como se señaló en mi comentario sobre la respuesta aceptada, el * puede ser útil para excluir cosas como archivos y directorios que comienzan con ".". Aunque, como observa, esto significa que los archivos y directorios eliminados del nivel superior en el origen no se eliminarán del directorio de destino. Por mi parte, no me importa si los archivos de nivel superior se eliminan correctamente del destino, solo importan los archivos debajo de los subdirectorios. Eliminar un subdirectorio de nivel superior es mucho menos probable que agregar uno, y estoy dispuesto a hacer un rm -r manual en el destino en ese improbable caso.
hollín