Ya copié terabytes de archivos, rsync
pero olvidé usarlos --archive
para preservar los atributos especiales de los archivos.
Intenté ejecutar rsync
nuevamente esta vez --archive
pero fue mucho más lento de lo que esperaba. ¿Existe alguna manera sencilla de hacer esto más rápido simplemente copiando metadatos de forma recursiva?
Respuesta1
Ok, puedes copiar el propietario, el grupo, el permiso y las marcas de tiempo usando el parámetro --reference
para chown
,, chmod
. touch
Aquí hay un script para hacerlo.
#!/bin/bash
# Filename: cp-metadata
myecho=echo
src_path="$1"
dst_path="$2"
find "$src_path" |
while read src_file; do
dst_file="$dst_path${src_file#$src_path}"
$myecho chmod --reference="$src_file" "$dst_file"
$myecho chown --reference="$src_file" "$dst_file"
$myecho touch --reference="$src_file" "$dst_file"
done
Debes ejecutarlo con sudo
(para permitir chown) y con dos parámetros: directorio de origen y destino. El guión sólo hace eco de lo que haría. Si está satisfecho cambie la línea myecho=echo
con myecho=
.
Respuesta2
Tratar la pregunta como "rsync solo tiene metadatos para copiar, entonces, ¿por qué es tan lento y cómo puedo hacerlo más rápido?":
rsync
Por lo general, utiliza tiempos iguales como heurística para detectar y omitir archivos sin cambios. Sin --archive
(específicamente, sin --times
), los tiempos m de los archivos de destino permanecen configurados en el momento en que los sincronizó, mientras que los tiempos m de los archivos de origen permanecen intactos (ignorando el engaño manual por su parte). Sin garantías externas de su parte de que el contenido de los archivos de origen no ha cambiado, rsync debe asumir que es posible que sí lo hayan hecho y, por lo tanto, debe verificarlos y/o copiarlos al destino nuevamente. Esto, más el hecho de que --whole-file
está implícito en las sincronizaciones locales->locales, lo convierte rsync
en --times
aproximadamente equivalente a cp
las sincronizaciones locales.
Siempre que sea aceptable actualizar el contenido de los archivos de destino, o si los archivos de origen no se han modificado desde la copia original, debería encontrar rsync --archive --size-only
más rápido que un rsync ingenuo.
Si tiene dudas sobre qué rsync
es lo que está tardando tanto en realizar la copia, se rsync --archive --dry-run --itemize-changes ...
lo informará de forma exhaustiva, aunque concisa.
Respuesta3
ADVERTENCIA: Sin soluciones especiales, GNU cp --attributes-only
truncará los archivos de destino, al menos en Precise. Vea la edición a continuación.
Original:
En esta situación, probablemente desee --attributes-only
la opción de GNU cp, junto con --archive
, ya que es un código probado y probado, tiene todos los atributos independientes del sistema de archivos y no sigue enlaces simbólicos (¡seguirlos puede ser malo!):
cp --archive --attributes-only /source/of/failed/backup/. /destination/
Al igual que con los archivos, cp
es aditivo con atributos extendidos: si tanto el origen como el destino tienen atributos extendidos,agregalos atributos extendidos del origen al destino (en lugar de eliminar primero todos los xattrs del destino). Si bien esto refleja cómo cp
se comporta si copia archivos en un árbol existente, es posible que no sea lo que espera.
También tenga en cuenta que si no conservó los enlaces físicos la primera vez rsync
pero desea conservarlos ahora, entoncescp
noarreglar eso por ti; probablemente sea mejor volver a ejecutar rsync
con las opciones correctas (consulte miotra respuesta) y ser paciente.
Si encontró esta pregunta mientras buscabadeliberadamenteseparar y recombinar metadatos/contenido de archivos, entonces es posible que desee echar un vistazo ametastoreque está en los repositorios de Ubuntu.
Fuente:manual de coreutils de gnu
Editado para agregar:
cp
de GNU coreutils
>= 8.17 y superiores funcionará como se describe, pero coreutils <= 8.16 truncará los archivos al restaurar sus metadatos. En caso de duda, no lo utilice cp
en esta situación; usar rsync
conlas opciones correctasy/o tener paciencia.
No recomendaría esto a menos que comprenda completamente lo que está haciendo, pero cp
se puede evitar que GNU anterior trunque archivos usando elTruco LD_PRELOAD:
/*
* File: no_trunc.c
* Author: D.J. Capelis with minor changes by Zak Wilcox
*
* Compile:
* gcc -fPIC -c -o no_trunc.o no_trunc.c
* gcc -shared -o no_trunc.so no_trunc.o -ldl
*
* Use:
* LD_PRELOAD="./no_trunc.so" cp --archive --attributes-only <src...> <dest>
*/
#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>
extern int errorno;
int (*_open)(const char *pathname, int flags, ...);
int (*_open64)(const char *pathname, int flags, ...);
int open(const char *pathname, int flags, mode_t mode) {
_open = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
flags &= ~(O_TRUNC);
return _open(pathname, flags, mode);
}
int open64(const char *pathname, int flags, mode_t mode) {
_open64 = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
flags &= ~(O_TRUNC);
return _open64(pathname, flags, mode);
}
Respuesta4
En las transferencias locales, cuando el origen y el destino están en sistemas de archivos montados localmente, rsync
siempre se copiará el contenido completo de los archivos. Para evitar esto puedes usar
rsync -a --no-whole-file source dest