¿Cómo puedo usar rsync para duplicar un árbol de directorios, creando enlaces duros a archivos?

23

De vez en cuando, tengo que realizar varios cambios importantes de migración en los archivos de datos en mi servidor, y estoy buscando una buena manera de hacerlo. Estaba pensando en usar rsync para duplicar la estructura de mi directorio comenzando en la carpeta de datos raíz, creando enlaces duros a todos los archivos originales (algunos de ellos son bastante grandes), y puedo sobrescribir en el árbol de destino solo los archivos que necesitan migrar. Al final, puedo cambiar con seguridad de los archivos antiguos a los nuevos con dos mvoperaciones.

Sin embargo, parece que no puedo obtener rsync para hacer esto. Lo intenté

rsync -a --link-dest=$DATA $DATA $DATA/../upgrade_tmp

pero en lugar de crear enlaces duros a archivos, rsync los copia por completo. ¿Hay algún problema al usar el mismo directorio fuente y link-dest?

Jean-Philippe Pellet
fuente

Respuestas:

21

rsync es una herramienta poderosa, pero desafortunadamente es extrañamente exigente con algunos de sus nombres de ruta.

Si $DATAes una ruta absoluta (es decir, comienza con a /), entonces la línea de comandos correcta para usar es:

rsync -a --link-dest=$DATA $DATA/ $DATA/../upgrade_tmp

[Ahora, solo un breve comentario sobre rsyncla extrañeza de. Tenga en cuenta el final /agregado al argumento de origen. Esto le indica rsyncque trabaje con el contenido del directorio fuente, en lugar de hacerlo con el directorio fuente en sí. (Supongo que $DATAaún no contiene un final /). En este caso, queremos trabajar con el contenido, por lo que agregamos el final /.]

Si, por otro lado, $DATAes una ruta relativa (es decir, no comienza con a /), entonces el comentario de Sean R --link-destes bang on: la ruta de enlace- destino se interpreta en relación con la ruta de destino , por lo que usaría lo siguiente:

rsync -a --link-dest=../`basename $DATA` $DATA/ $DATA/../upgrade_tmp

EDITAR

Una nota final, resulta que la segunda rsynclínea de comando que di debería funcionar independientemente de si $DATAes una ruta absoluta, ya que basenameno le importa si una ruta es absoluta o relativa.

Steven Monday
fuente
1
Solo una barra faltante, quién habría pensado en eso ... ¡Gracias por la buena explicación!
Jean-Philippe Pellet
Gracias por esto, intenté seguir varias instrucciones de copia de seguridad incrementales, como esta, y no encontré ninguna mención de esta peculiaridad. Esto fue lo único que realmente aseguró que los archivos estuvieran vinculados. Verificando que el recuento de referencias fue> 1 y los números de inodo fueron los mismos conls -ilah
Walf
Lo utilicé junto con la función relpath () descrita en unix.stackexchange.com/a/85068/57414 para hacer una copia de seguridad de un $SOURCEdirectorio en un $TARGETdirectorio como este:SOURCE='abs_path_to_backup'; TARGET='.'; rsync -a --link-dest=$(relpath $TARGET $SOURCE) $SOURCE/ $TARGET/
Nathan S. Watson-Haigh
13

Lo que quieres es "cp -al":

cp -al $DATA/ $DATA/../upgrade_tmp/
  • -a recurre como rsync -a
  • -l vincularé los archivos en lugar de copiarlos.
Sean Reifschneider
fuente
1
cp -allamentablemente no está disponible en mi sistema (Mac OS X 10.6). Usaré pax en su lugar ...
Jean-Philippe Pellet
7

La --link-destopción en rsynces relativa al directorio de destino , no al directorio actual. Entonces, lo que quieres es:

rsync -a --link-dest=../`basename $DATA` $DATA $DATA/../upgrade_tmp
Sean Reifschneider
fuente
Vaya, quise decir basename, originalmente tenía dirname.
Sean Reifschneider
1
La página de manual dice que esa --link-destopción, si es relativa , es relativa al directorio de destino. En mi caso es absoluto. Incluso hacerlo relativo al directorio de destino no hace que esto funcione.
Jean-Philippe Pellet
7

Resulta que es más difícil hacer esto rsynccon otras herramientas. La respuesta correcta para rsynces Steven Monai de, pero la forma más sencilla de hacerlo es utilizar cualquiera cp -alo pax -rwlen sistemas donde -lno es una opción válida para cp:

pax -rwl $DATA $DATA/../upgrade_tmp

o

cp -al $DATA/ $DATA/../upgrade_tmp/
Jean-Philippe Pellet
fuente
4

Esto funciona para mi:

$ rsync --hard-links --recursive --link-dest=/local user@host:/remote/ /local

Yo uso rsync versión 3.1.0.

Del hombre :

- enlaces duros

Le dice a rsync que busque archivos vinculados en la transferencia, sin esta opción, los archivos vinculados en la transferencia se tratan como si fueran archivos separados.

--link-dest = DIR

Los archivos no modificados están vinculados desde DIR al directorio de destino. Los archivos deben ser idénticos en todos los atributos conservados (por ejemplo, permisos, posiblemente propiedad) para que los archivos se vinculen entre sí.

Alexander Fedorov
fuente
2
Solo el fragmento de código no es suficiente, explique qué hace y por qué.
Peter dice reinstalar a Mónica el
--hard-links Le dice a rsync que busque archivos vinculados en la transferencia, sin esta opción, los archivos vinculados en la transferencia se tratan como si fueran archivos separados. --link-dest = DIR Los archivos sin cambios están vinculados desde DIR al directorio de destino. Los archivos deben ser idénticos en todos los atributos preservados (por ejemplo, permisos, posiblemente propiedad) para que los archivos se vinculen entre sí.
Alexander Fedorov
1
Maravilloso. Gracias. En realidad, encontré su respuesta en la cola de "baja calidad". Significa que hubo un voto si su respuesta se debe eliminar o no. Pero no solo el peligro de las eliminaciones es una razón para tratar de dar una respuesta "humana" bien formateada, sino que también ayuda mucho si desea obtener votos a favor.
Peter dice que reinstale a Mónica
2

Puede intentar seguir el enlace http://www.lessfs.com/wordpress/ es trabajar en COW (copiar al escribir) que ahorrará tiempo y espacio

Rajat
fuente
lessfs es muy interesante, pero también es muy experimental. No recomendado para uso de producción todavía.
mattdm
2

Primero cree los directorios solo en el destino:

rsync -av --include '*/' --exclude '*' /source/ /destination/

Luego enlace duro solo los archivos:

cd /source
find . -type f -exec ln -v {} /destination/{} \;
Cakemox
fuente
Gracias, en realidad, podría usarlo paxcomo se muestra en mi comentario anterior, lo que parece más fácil.
Jean-Philippe Pellet
1

Use la Opción -H para preservar los enlaces duros y leer la página de manual.

Texas
fuente
1
-H no funciona. No tengo enlaces duros para preservar en mi árbol fuente, solo quiero una copia simple de mi árbol fuente donde en la copia, todos los archivos están enlazados a los archivos originales. Lo siento en mi pregunta original no estaba claro ...
Jean-Philippe Pellet
¿Es "leer la página de manual" una respuesta? :-)
meduz 01 de