Come sincronizzare due cartelle con gli strumenti da riga di comando?


63

Dopo essere migrato su Linux da Windows, vorrei trovare un software alternativo a Winmerge o piuttosto imparare strumenti da riga di comando per confrontare e sincronizzare due cartelle su Linux. Le sarei grato se potessi dirmi come svolgere le seguenti attività sulla riga di comando ... (Ho studiato diff e rsync, ma ho ancora bisogno di aiuto.)

Abbiamo due cartelle: "/ home / user / A" e "/ home / user / B"

La cartella A è il luogo in cui vengono salvati i file e le cartelle normali e la cartella B è una cartella di backup che funge da mirror completo della cartella A. (Nulla viene salvato o modificato direttamente dall'utente nella cartella B.)

Le mie domande sono:

  • Come elencare i file che esistono solo nella cartella B? (Ad esempio quelli eliminati dalla cartella A dall'ultima sincronizzazione.)

  • Come copiare i file presenti solo nella cartella B nella cartella A?

  • Come elencare i file esistenti in entrambe le cartelle ma con timestamp o dimensioni diverse? (Quelli che sono stati modificati nella cartella A dall'ultima sincronizzazione. Vorrei evitare di usare checksum, perché ci sono decine di migliaia di file e renderebbe il processo troppo lento.)

  • Come fare una copia esatta della cartella A nella cartella B? Voglio dire, copia tutto dalla cartella A nella cartella B che esiste solo nella cartella A ed elimina tutto dalla cartella B che esiste solo nella cartella B, ma senza toccare i file uguali in entrambe le cartelle.


Perché non utilizzare un programma di backup adeguato per questo? La duplicità è un esempio.
Qudit,

Risposte:


88

Ciò inserisce la cartella A nella cartella B:

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

Se vuoi che il contenuto delle cartelle A e B sia lo stesso, inserisci /home/user/A/(con la barra) come sorgente. Questo non prende la cartella A ma tutto il suo contenuto e lo mette nella cartella B. In questo modo:

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a Esegui la sincronizzazione preservando tutti gli attributi del filesystem
  • -v correre verbosamente
  • -u copia i file solo con un tempo di modifica più recente (o differenza di dimensioni se i tempi sono uguali)
  • --delete elimina i file nella cartella di destinazione che non esistono nel sorgente

Manpage: https://download.samba.org/pub/rsync/rsync.html


7
rsync : eseguire app rsync, -a : fare la sincronizzazione conservare tutti gli attributi del filesystem, -v : correre verbosely, -z : comprimere i dati durante la sincronizzazione (trasportare i dati in modalità compressa), --delete : eliminare i file in target cartella che non esiste nel sorgente, / home / user / A : cartella sorgente, / home / user / B : cartella target
SonicARG

Ciao SonicARG, ho completamente dimenticato di tornare a questo e di inserire la spiegazione, grazie all'invio della spiegazione, ho inserito il tuo nella risposta, spero non ti dispiaccia.
TuxForLife,

6
Rsync è pensato principalmente per copiare file tra computer diversi, come spiegato qui può servire anche allo scopo di sincronizzare le directory. Quindi l'opzione -z è interessante per ridurre il traffico di rete e quindi migliorare le prestazioni di una sincronizzazione tra 2 computer: (leggi i dati dal disco -> comprimi) === rete ===> (decomprimi-> scrivi sul disco) Usando - z sincronizzare 2 directory sullo stesso host è un po 'sciocco e spreco di cicli cpu come si otterrebbe (leggi i dati dal disco -> comprimi -> decomprimi -> scrivi sul disco)
GerritCap

@GerritCap, ho fatto una modifica, grazie per il tuo prezioso contributo
TuxForLife,

1
Ho provato il comando ma crea una sotto-directory /home/user/B/Ainvece di sovrascrivere il contenuto di A in quello di B. Potresti aiutarmi a dargli un'occhiata?
Luca,

11

Potresti creare uno unisonstrumento sviluppato da Benjamin Pierce presso U Penn.

Supponiamo che tu abbia due directory,

/home/user/Documents/dirA/ e /home/user/Documents/dirB/

Per sincronizzare questi due, è possibile utilizzare:

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

Nell'output, unisonverranno visualizzate tutte le directory e i file diversi nelle due directory che è stato chiesto di sincronizzare. Raccomanderà di sincronizzare in modo addizionale (replicare il file mancante in entrambe le posizioni) sulla corsa iniziale, quindi creare e mantenere un albero di sincronizzazione sulla macchina e, nelle corse successive, implementerà la sincronizzazione vera (cioè, se si elimina un file da .../dirA, verrà eliminato .../dirBanche. Puoi anche confrontare ogni modifica e facoltativamente scegliere di inoltrare o invertire la sincronizzazione tra le due directory.

Opzionalmente, per avviare l'interfaccia grafica, è sufficiente rimuovere l' -ui textopzione dal tuo comando, anche se trovo il clipiù semplice e veloce da usare.

Altre informazioni: tutorial Unison nella documentazione utente di Unison .


1

La risposta di TuxForLife è piuttosto buona, ma ti consiglio caldamente di usarla -cdurante la sincronizzazione locale. Puoi sostenere che non vale la pena tempo / rete per farlo per le sincronizzazioni remote, ma ne vale la pena per i file locali perché la velocità è così 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.

Questo mostra come avere le stesse dimensioni e timestamp può fallire.

Il set up

$ 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

Il rsync che non copia nulla perché tutti i file hanno le stesse dimensioni e il timestamp

$ 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    

Il rsync che funziona correttamente perché confronta i checksum

$ 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

-c e -u funzionano bene insieme?
Sergey Korzhov,

@SergeyKorzhov lo fa. `-U 'funziona ancora come al solito per aggiornarsi solo se la destinazione non è più recente.
Bruno Bronosky,

1

Questo è quello che sto usando per il backup dei file personali, dove non mi interessa tutto ciò che è coperto -ae voglio che vengano stampate informazioni più utili.

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

Dalla pagina man di rsync :

-r, --recursive
Questo dice a rsync di copiare ricorsivamente le directory.

-t, --times
Questo dice a rsync di trasferire i tempi di modifica insieme ai file e di aggiornarli sul sistema remoto.

-u, --update
Questo forza rsync a saltare qualsiasi file esistente sulla destinazione e con un orario modificato più recente del file sorgente. (Se un file di destinazione esistente ha un tempo di modifica uguale al file di origine, verrà aggiornato se le dimensioni sono diverse.)

--delete
Questo dice a rsync di cancellare file estranei dal lato ricevente (quelli che non sono dal lato mittente), ma solo per le directory che sono sincronizzate.

--info = FLAGS
Questa opzione consente di avere un controllo accurato sull'output di informazioni che si desidera vedere.

A partire dal 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)

Sebbene meno esplicito, questo è apparentemente equivalente e più breve:

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

-v, --verbose
Un singolo -v fornisce informazioni su quali file vengono trasferiti e un breve riepilogo alla fine [stats1].


0

Questo non è completamente lo stesso di quello che chiedi, ma potresti prendere in considerazione l'utilizzo di uno strumento di controllo della versione. Strumenti come Git fanno tutto ciò che chiedi, e altro ancora, specialmente se non lavori direttamente nella cartella B, potrebbe essere interessante dargli un'occhiata. puoi trovare qualche informazione in più su git qui


2
Funziona solo se sei disposto ad aggiungere tutto al controllo della versione. Inoltre, impone di archiviare permanentemente ogni modifica mai commessa, il che potrebbe essere indesiderabile.
Qudit,

@Qudit, questo è vero, anche se è possibile tramite la clonazione limitare la cronologia, ma limitare la cronologia non è (ancora?) Implementato in Git per impostazione predefinita.
switch87,

@ switch87 Sì, lo so che puoi eliminare i vecchi commit. Tuttavia, il controllo della versione non è una soluzione appropriata per i backup generici, soprattutto se ci sono file binari di grandi dimensioni.
Qudit,

La sua domanda è per il backup locale, ma se lo usi per il backup remoto puoi comunque usare git annex per i file più grandi. per il backup locale questo non è un problema.
switch87,

2
@ switch87 Questo avrebbe dovuto essere un commento alla Q e non una risposta poiché non spiega come avresti usato git per fare i backup.
slm

0

Puoi usarlo in questo modo:

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

In questo modo copierai il contenuto della cartella A nella cartella B, non il contenuto della cartella A stessa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.