¿Cómo copiar directorios con la preservación de enlaces duros?

40

¿Cómo mover directorios que tienen archivos en común de una a otra partición?

Supongamos que tenemos una partición montada en /mnt/Xdirectorios que comparten archivos con enlaces duros. Cómo mover dichos directorios a otra partición, que sea /mnt/Ycon la preservación de esos enlaces duros.

Para una mejor ilustración, ¿qué quiero decir con "directorios que comparten archivos en común con enlaces duros"? Aquí hay un ejemplo:

# let's create three of directories and files
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
# and copy it with hardlinks
cp -r -l a hardlinks_of_a

Para ser más específicos, supongamos que el tamaño total de los archivos es 10G y cada archivo tiene 10 enlaces duros. La pregunta es cómo moverlo al destino con el uso de 10G (alguien podría decir sobre copiarlo con 100G y luego ejecutar la deduplicación; no es lo que estoy preguntando)

Grzegorz Wierzowiecki
fuente

Respuestas:

29

Primera respuesta: la forma GNU

GNU cp -acopia de manera recursiva conservando la mayor estructura y metadatos posible. Los enlaces duros entre archivos en el directorio fuente están incluidos en eso. Para seleccionar la preservación del enlace duro específicamente sin todas las otras características de -a, use --preserve=links.

mkdir src
cd src
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
cp -r -l a hardlinks_of_a
cd ..
cp -a src dst
Alan Curry
fuente
3
+1 en tar, -1 para usar argumentos específicos de gnu para cp.
WhyNotHugo
Diste tres respuestas en una. ¿Podría dividirlos en tres para que puedan comentarse y evaluarse por separado? (Sugerencia: puede editar esto, para dejar solo uno, por ejemplo "cp -a". Más adelante agregue dos más, para "tar" y "pax")
Grzegorz Wierzowiecki
1
@GrzegorzWierzowiecki división lograda
Alan Curry
66
@Hugo: no hay nada de malo en usar argumentos específicos de GNU para herramientas estándar. Las versiones de GNU son el estándar de facto en estos días, e incluso cuando no estaban preinstaladas, era una práctica común instalar las herramientas de GNU (sé que siempre lo hice, simplemente eran mejores que, por ejemplo, las versiones solaris y * bsd , y proporcionaron consistencia entre diferentes * nixes). Probablemente sea una buena práctica señalar GNUisms cuando los use, pero no es obligatorio. Además, Grzegorz no dijo "no en Linux", por lo que es razonable suponer que ese es el entorno del que habla.
cas
1
@WhyNotHugo: ¿Cómo es POSIX "puede ser más estándar?". POSIX es lo que nos trajo a donde estamos. ¿Sabía que todas las versiones de Windows desde Windows NT son totalmente compatibles con POSIX? Tienen una limitación de longitud de ruta de 255 caracteres cuando se utilizan las funciones de E / S del archivo POSIX, lo que las vuelve inútiles. ¿Sabía que Solaris, Irix, HP-UX cumplen con POSIX y, sin embargo, todos los argumentos de sus herramientas difieren (por ejemplo, tar)? cp -a es un requisito mínimo para cualquier versión de cp que quiera reemplazar la copia GNU.
Johannes Overmann
37

rsync tiene una opción -Hu --hard-linksopción para esto, y tiene los beneficios habituales de rsync de poder detenerse y reiniciarse, y volver a ejecutarse para tratar eficientemente cualquier archivo que se haya cambiado durante / después de la ejecución anterior.

-H, --hard-links
    This tells rsync to look for hard-linked files in
    the source and link together the corresponding
    files on the destination.  Without  this option,
    hard-linked files in the source are treated as
    though they were separate files. [...]

Lea la rsyncpágina de manual y busque -H. Hay muchos más detalles sobre advertencias particulares.

cas
fuente
2
Lo he comprobado, funciona.
Grzegorz Wierzowiecki
si, lo sé. Lo he estado usando durante años en mis scripts de respaldo. también para mover archivos entre sistemas de archivos como en su pregunta.
cas
rsync usa cantidades de memoria cuando crea su lista de archivos. Para mí, después de muchas horas de "Construir la lista de archivos ...", llenó mis 16 GB de memoria y salió sin haber copiado nada. YMMV.
msc
2
Desde man rsync: Comenzando con rsync 3.0.0, el algoritmo recursivo utilizado ahora es un escaneo incremental que usa mucha menos memoria que antes y comienza la transferencia después de que se haya completado el escaneo de los primeros directorios. Este escaneo incremental solo afecta nuestro algoritmo de recursión y no cambia una transferencia no recursiva. También solo es posible cuando ambos extremos de la transferencia son al menos la versión 3.0.0. Tenga en cuenta que ambos --delete-beforey --delete-afterdeshabilitar este algoritmo mejorado.
cas
Además, aunque rsynces una herramienta increíblemente útil, no siempre es la mejor herramienta para cada trabajo. En estos días, prefiero usar conjuntos de datos ZFS para poder hacer instantáneas y zfs sendellos, principalmente uso rsync en sistemas de archivos que no son ZFS. btrfstiene una instantánea similar + capacidad de envío.
cas
14

Tercera respuesta: la manera POSIX

POSIX no ha estandarizado la tarutilidad, aunque sí ha estandarizado el tarformato de archivo. Se llama a la utilidad POSIX para manipular archivos tar paxy tiene la característica adicional de poder hacer la operación de empaque y desempaque en un solo proceso.

mkdir dst
pax -rw src dst
Alan Curry
fuente
10

Segunda respuesta: La antigua forma de UNIX

Cree un archivo tar en el directorio de origen, envíelo por una tubería y descomprímalo en el directorio de destino.

# create src as before
(cd src;tar cf - .) | (mkdir dst;cd dst;tar xf -)
Alan Curry
fuente
1
marcado -> funciona. Enlaces conservados.
Grzegorz Wierzowiecki
1
¿Alguna idea de por qué esto realmente preserva los enlaces duros?
Peter
1
Porque tarconserva los enlaces duros. En GNU tar, al menos, puede deshabilitar este comportamiento con--hard-dereference
cas
En mi caso, al intentar copiar una gran jerarquía de directorios (una copia de seguridad de TimeMachine), tar preservó algunos enlaces duros pero en algunos casos replicó el archivo. Creo que esto se debe a tar xque no tiene la lista completa de archivos ya que los archivos aún se están canalizando desde tar c. Probablemente, si guardó todo el archivo antes de extraerlo, estaría bien. Estaría muy feliz si alguien pudiera confirmar esa teoría.
msc
10

Fuente: http://www.cyberciti.biz/faq/linux-unix-apple-osx-bsd-rsync-copy-hard-links/

Lo que necesita para hacer una copia exacta es

rsync -az -H --delete --numeric-ids /path/to/source/ /path/to/dest/
Pykler
fuente
Vea mi comentario sobre rsync arriba.
msc
1
Sospecho que esto no copiará las ACL, los atributos extendidos, etc. La versión de Linux también tiene las opciones -A y -X para preservarlas, pero creo que no tienes suerte en MacOS.
Edward Falk