¿Cómo sincronizar dos carpetas con herramientas de línea de comandos?

63

Habiendo migrado a Linux desde Windows, me gustaría encontrar un software alternativo a Winmerge o más bien aprender herramientas de línea de comandos para comparar y sincronizar dos carpetas en Linux. Le agradecería que me dijera cómo realizar las siguientes tareas en la línea de comandos ... (He estudiado diff y rsync, pero aún necesito ayuda).

Tenemos dos carpetas: "/ home / user / A" y "/ home / user / B"

La carpeta A es el lugar donde se guardan los archivos y carpetas normales y la carpeta B es una carpeta de respaldo que sirve como un espejo completo de la carpeta A. (El usuario no guarda o modifica directamente nada en la carpeta B.)

Mis preguntas son:

  • ¿Cómo enumerar los archivos que existen solo en la carpeta B? (Por ejemplo, los borrados de la carpeta A desde la última sincronización).

  • ¿Cómo copiar archivos que existen solo en la carpeta B en la carpeta A?

  • ¿Cómo enumerar los archivos que existen en ambas carpetas pero que tienen diferentes marcas de tiempo o tamaños? (Los que se han modificado en la carpeta A desde la última sincronización. Me gustaría evitar el uso de sumas de verificación, porque hay decenas de miles de archivos y el proceso sería demasiado lento).

  • ¿Cómo hacer una copia exacta de la carpeta A en la carpeta B? Quiero decir, copie todo de la carpeta A a la carpeta B que existe solo en la carpeta A y elimine todo de la carpeta B que exista solo en la carpeta B, pero sin tocar los archivos que son iguales en ambas carpetas.

akopacsi
fuente
¿Por qué no usar un programa de respaldo adecuado para esto? La duplicidad es un ejemplo.
Qudit

Respuestas:

88

Esto pone la carpeta A en la carpeta B:

rsync -avu --delete "/home/user/A" "/home/user/B"  

Si desea que el contenido de las carpetas A y B sea ​​el mismo, coloque /home/user/A/(con la barra inclinada) como fuente. Esto no toma la carpeta A sino todo su contenido y lo coloca en la carpeta B. De esta manera:

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a Realice la sincronización conservando todos los atributos del sistema de archivos
  • -v corre verbosely
  • -u solo copie archivos con un tiempo de modificación más reciente (o diferencia de tamaño si los tiempos son iguales)
  • --delete eliminar los archivos en la carpeta de destino que no existen en la fuente

Página de manual: https://download.samba.org/pub/rsync/rsync.html

TuxForLife
fuente
77
rsync : ejecute la aplicación rsync, -a : realice la sincronización conservando todos los atributos del sistema de archivos, -v : ejecute de forma detallada, -z : comprima los datos durante la sincronización (transporte los datos en modo comprimido), --delete : elimine los archivos en el destino carpeta que no existe en la fuente, / home / user / A : carpeta de origen, / home / user / B : carpeta de destino
SonicARG
Hola SonicARG, olvidé por completo volver a esto y poner la explicación, gracias enviando la explicación, puse la tuya en la respuesta, espero que no te importe.
TuxForLife
66
Rsync está destinado principalmente a copiar archivos entre diferentes computadoras, como se explica aquí, también puede servir para sincronizar directorios. Entonces, la opción -z es interesante para reducir el tráfico de red y así mejorar el rendimiento de una sincronización entre 2 computadoras: (leer datos del disco -> comprimir) === red ===> (descomprimir-> escribir en el disco) Usar - z para sincronizar 2 directorios en el mismo host es un poco tonto y desperdicia los ciclos de CPU que obtendría (leer datos del disco -> comprimir -> descomprimir -> escribir en el disco)
GerritCap
@GerritCap, hice una edición, gracias por su valioso aporte
TuxForLife
1
He probado el comando pero crea un subdirectorio en /home/user/B/Alugar de sobrescribir el contenido de A al contenido de B. ¿Podrías ayudarme a echarle un vistazo?
Lucas
11

Podrías unisondesarrollar una herramienta desarrollada por Benjamin Pierce en U Penn.

Supongamos que tiene dos directorios,

/home/user/Documents/dirA/ y /home/user/Documents/dirB/

Para sincronizar estos dos, puede usar:

~ $unison -ui text /home/user/Documents/dirA/ /home/user/Documents/dirB/

En la salida, unisonse mostrarán todos y cada uno de los directorios y archivos que sean diferentes en los dos directorios que solicitó sincronizar. Se recomendará sincronizar aditivamente (replicar el archivo faltante en ambas ubicaciones) en la ejecución inicial, luego crear y mantener un árbol de sincronización en su máquina, y en las ejecuciones posteriores implementará una sincronización verdadera (es decir, si elimina un archivo .../dirA, también se eliminará .../dirB. También puede comparar todos y cada uno de los cambios y, opcionalmente, elegir sincronizar hacia adelante o hacia atrás entre los dos directorios.

Opcionalmente, para iniciar la interfaz gráfica, simplemente elimine la -ui textopción de su comando, aunque considero que es climás simple y rápido de usar.

Más sobre esto: Tutorial de Unison en la documentación de usuario de Unison .

Aalok
fuente
1

La respuesta de TuxForLife es bastante buena, pero le sugiero encarecidamente que la use -cal sincronizar localmente. Puede argumentar que no vale la pena el tiempo / la penalización de la red para realizar sincronizaciones remotas, pero vale la pena para los archivos locales porque la velocidad es muy grande.

-c, --checksum
       This forces the sender to checksum every regular file using a 128-bit  MD4
       checksum.   It  does this during the initial file-system scan as it builds
       the list of all available files. The receiver then checksums  its  version
       of  each  file  (if  it exists and it has the same size as its sender-side
       counterpart) in order to decide which files need to be updated: files with
       either  a  changed  size  or a changed checksum are selected for transfer.
       Since this whole-file checksumming of all files on both sides of the  con-
       nection  occurs  in  addition to the automatic checksum verifications that
       occur during a file's transfer, this option can be quite slow.

       Note that rsync always verifies that each transferred file  was  correctly
       reconstructed  on  the receiving side by checking its whole-file checksum,
       but that automatic after-the-transfer verification has nothing to do  with
       this  option's  before-the-transfer  "Does  this file need to be updated?"
       check.

Esto muestra cómo tener el mismo tamaño y marcas de tiempo puede fallarle.

La puesta en marcha

$ cd /tmp

$ mkdir -p {A,b}/1/2/{3,4}

$ echo "\___________from A" | \
      tee A/1/2/x  | tee A/1/2/3/y  | tee A/1/2/4/z  | \
  tr A b | \
      tee b/1/2/x  | tee b/1/2/3/y  | tee b/1/2/4/z  | \
      tee b/1/2/x0 | tee b/1/2/3/y0 >     b/1/2/4/z0

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b

El rsync que no copia nada porque todos los archivos tienen el mismo tamaño y marca de tiempo

$ rsync -avu A/ b
building file list ... done

sent 138 bytes  received 20 bytes  316.00 bytes/sec
total size is 57  speedup is 0.36

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b    

El rsync que funciona correctamente porque compara sumas de verificación

$ rsync -cavu A/ b
building file list ... done
1/2/x
1/2/3/y
1/2/4/z

sent 381 bytes  received 86 bytes  934.00 bytes/sec
total size is 57  speedup is 0.12

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from A
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from A
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from A
b/1/2/x0
\___________from b
Bruno Bronosky
fuente
¿-c y -u funcionan bien juntos?
Sergey Korzhov
@SergeyKorzhov lo hace. La '-u' todavía funciona como de costumbre para actualizar solo si el destino no es más nuevo.
Bruno Bronosky
1

Esto es lo que estoy usando para hacer copias de seguridad de archivos personales, donde no me importa todo lo que cubre -a, y quiero que se imprima más información útil.

rsync -rtu --delete --info=del,name,stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

Desde la página de manual de rsync :

-r, --recursive
Esto le dice a rsync que copie directorios recursivamente.

-t, --times
Esto le dice a rsync que transfiera los tiempos de modificación junto con los archivos y los actualice en el sistema remoto.

-u, --update
Esto obliga a rsync a omitir cualquier archivo que exista en el destino y tenga una hora modificada que sea más reciente que el archivo fuente. (Si un archivo de destino existente tiene un tiempo de modificación igual al del archivo de origen, se actualizará si los tamaños son diferentes).

--delete
Esto le dice a rsync que elimine los archivos extraños del lado receptor (los que no están en el lado emisor), pero solo para los directorios que se están sincronizando.

--info = BANDERAS
Esta opción le permite tener un control detallado sobre la salida de información que desea ver.

De rsync --info=help

DEL        Mention deletions on the receiving side  
NAME       Mention 1) updated file/dir names, 2) unchanged names  
STATS      Mention statistics at end of run (levels 1-3)

Aunque menos explícito, esto es aparentemente equivalente y más corto:

rsync -rtuv --delete --info=stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

-v, --verbose
Un simple -v le dará información sobre qué archivos se están transfiriendo y un breve resumen al final [stats1].

Abe honesto
fuente
0

Esto no es completamente lo mismo que pide, pero podría considerar usar una herramienta de control de versiones. Las herramientas como Git hacen todo lo que pides y más, especialmente si no trabajas directamente en la carpeta B, podría ser interesante echarle un vistazo. puedes encontrar más información sobre git aquí

switch87
fuente
2
Esto solo funciona si está dispuesto a agregar todo al control de versiones. También obliga a cada cambio comprometido a almacenarse permanentemente, lo que puede ser indeseable.
Qudit
@Qudit, eso es cierto, aunque es posible mediante la clonación limitar el historial, pero la limitación del historial no está (¿todavía?) Implementada en Git de forma predeterminada.
switch87
@ switch87 Sí, sé que puede eliminar las confirmaciones antiguas. Sin embargo, el control de versiones no es realmente una solución adecuada para las copias de seguridad genéricas, especialmente si hay archivos binarios grandes.
Qudit
Su pregunta es para la copia de seguridad local, pero si la usa para la copia de seguridad remota, aún puede usar git annex para los archivos más grandes. para copias de seguridad locales esto no es un problema.
switch87
2
@ switch87 Esto realmente debería haber sido un comentario a la Q y no una respuesta, ya que no explica cómo usaría git para hacer copias de seguridad.
slm
0

Puedes usarlo de esta manera:

rsync -avu --delete /home/user/A/* /home/user/B/

De esta manera, copiará el contenido de la carpeta A en la carpeta B, no el contenido de la carpeta A en sí.

Isaias Sanchez
fuente