La mejor manera de sincronizar archivos: copie solo archivos EXISTENTES y solo si ES MÁS NUEVO que el destino

18

Estoy haciendo esta sincronización localmente en Ubuntu 12.04. Los archivos son generalmente pequeños archivos de texto (código).

Quiero copiar (preservar mtime stamp) del sourcedirectorio, targetpero solo quiero copiar si el archivo target ya existe y es anterior al anteriorsource .

Por lo tanto, solo estoy copiando archivos que son más nuevos source, pero deben existir targeto no se copiarán. ( sourcetendrá muchos más archivos que target.)

Realmente estaré copiando de sourcea múltiples targetdirectorios. Menciono esto en caso de que afecte la elección de la solución. Sin embargo, puedo ejecutar fácilmente mi comando varias veces, especificando el nuevo targetcada vez, si eso es lo que se requiere.

MountainX para Monica Cellio
fuente

Respuestas:

29

Creo que puedes usar rsyncpara hacer esto. La observación clave sería la necesidad de usar los interruptores --existingy --update.

        --existing              skip creating new files on receiver
        -u, --update            skip files that are newer on the receiver

Un comando como este lo haría:

$ rsync -avz --update --existing src/ dst

Ejemplo

Digamos que tenemos los siguientes datos de muestra.

$ mkdir -p src/; touch src/file{1..3}
$ mkdir -p dst/; touch dst/file{2..3}
$ touch -d 20120101 src/file2

Que se ve de la siguiente manera:

$ ls -l src/ dst/
dst/:
total 0
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file2
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file3

src/:
total 0
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file1
-rw-rw-r--. 1 saml saml 0 Jan  1  2012 file2
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file3

Ahora, si tuviera que sincronizar estos directorios, no pasaría nada:

$ rsync -avz --update --existing src/ dst
sending incremental file list

sent 12 bytes  received 31 bytes  406.00 bytes/sec
total size is 0  speedup is 0.00

Si tenemos touchun archivo fuente para que sea más nuevo:

$ touch src/file3 
$ ls -l src/file3
-rw-rw-r--. 1 saml saml 0 Feb 27 01:04 src/file3

Otra ejecución del rsynccomando:

$ rsync -avz --update --existing src/ dst
sending incremental file list
file3

sent 115 bytes  received 31 bytes  292.00 bytes/sec
total size is 0  speedup is 0.00

Podemos ver que file3, dado que es más nuevo y que existe dst/, se envía.

Pruebas

Para asegurarse de que funcionan las cosas antes de cortar el comando suelta, me gustaría sugerir el uso de otro de rsynclos interruptores 's, --dry-run. Agreguemos otro -vtambién para que rsyncel resultado sea más detallado.

$ rsync -avvz --dry-run --update --existing src/ dst 
sending incremental file list
delta-transmission disabled for local transfer or --whole-file
file1
file2 is uptodate
file3 is newer
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 88 bytes  received 21 bytes  218.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)
slm
fuente
Gracias. ¿No necesito algunas opciones más de rsync? Estoy leyendo la página del manual. Parece que podría necesitar lo siguiente: rsync --archive --update --existing --whole-file --itemize-changes a/ b. ¿O son innecesarias la mayoría de esas opciones? (
Agregué un
@MountainX: solo agrega las opciones que necesites. Me gustaría empezar con -aeso es un superconjunto de interruptores, -rlptgoD.
slm
Déjame aclarar eso. Estoy confundido acerca de --updatey --existing. ¿Necesito ambos? Probé su solución y parece funcionar, pero todavía me siento más seguro al agregar --update.
MountainX para Monica Cellio
@MountainX: seguro que puedes agregarlo, lo pondré en la A también.
slm