Jak zsynchronizować dwa foldery za pomocą narzędzi wiersza poleceń?


63

Po migracji do systemu Linux z systemu Windows chciałbym znaleźć alternatywne oprogramowanie dla Winmerge lub raczej nauczyć się narzędzi wiersza poleceń do porównywania i synchronizacji dwóch folderów w systemie Linux. Byłbym wdzięczny, gdybyś mógł mi powiedzieć, jak wykonać następujące zadania w wierszu polecenia ... (Studiowałem diff i rsync, ale nadal potrzebuję pomocy).

Mamy dwa foldery: „/ home / user / A” i „/ home / user / B”

Folder A to miejsce, w którym zapisywane są zwykłe pliki i foldery, a folder B jest folderem kopii zapasowej, który służy jako pełne lustro folderu A. (Użytkownik nie zapisuje ani nie modyfikuje bezpośrednio w folderze B.)

Moje pytania to:

  • Jak wyświetlić listę plików, które istnieją tylko w folderze B? (Np. Te usunięte z folderu A od ostatniej synchronizacji.)

  • Jak skopiować pliki istniejące tylko w folderze B z powrotem do folderu A?

  • Jak wyświetlić listę plików, które istnieją w obu folderach, ale mają różne znaczniki czasu lub rozmiary? (Te, które zostały zmodyfikowane w folderze A od ostatniej synchronizacji. Chciałbym unikać używania sum kontrolnych, ponieważ istnieją dziesiątki tysięcy plików, co spowodowałoby, że proces byłby zbyt wolny.)

  • Jak zrobić dokładną kopię folderu A do folderu B? Mam na myśli, skopiuj wszystko z folderu A do folderu B, który istnieje tylko w folderze A i usuń wszystko z folderu B, który istnieje tylko w folderze B, ale bez dotykania plików, które są takie same w obu folderach.


Dlaczego nie użyć do tego odpowiedniego programu do tworzenia kopii zapasowych? Podwójność jest jednym z przykładów.
Qudit

Odpowiedzi:


88

Spowoduje to umieszczenie folderu A w folderze B:

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

Jeśli chcesz, aby zawartość folderów A i B była taka sama, wstaw /home/user/A/(z ukośnikiem) jako źródło. To nie bierze folderu A, ale całą jego zawartość i umieszcza go w folderze B. Tak:

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a Wykonaj synchronizację zachowując wszystkie atrybuty systemu plików
  • -v biegać werbalnie
  • -u kopiuj tylko pliki z nowszym czasem modyfikacji (lub różnicą rozmiaru, jeśli czasy są równe)
  • --delete usuń pliki w folderze docelowym, które nie istnieją w źródle

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


7
rsync : uruchom aplikację rsync, -a : wykonaj synchronizację zachowując wszystkie atrybuty systemu plików, -v : uruchom słownie, -z : kompresuj dane podczas synchronizacji (transportuj dane w trybie skompresowanym), --delete : usuń pliki w celu folder, który nie istnieje w źródle, / home / user / A : folder źródłowy, / home / user / B : folder docelowy
SonicARG

Cześć SonicARG, całkowicie zapomniałem wrócić do tego i podać wyjaśnienie, dziękuję, przesyłając wyjaśnienie, podaję twoje odpowiedzi, mam nadzieję, że nie masz nic przeciwko.
TuxForLife,

6
Rsync jest przeznaczony przede wszystkim do kopiowania plików między różnymi komputerami, jak wyjaśniono tutaj, może również służyć do synchronizacji katalogów. Tak więc opcja -z jest interesująca w celu zmniejszenia ruchu sieciowego, a tym samym zwiększenia wydajności rsync między 2 komputerami: (odczyt danych z dysku -> kompresja) === sieć ===> (rozpakowanie -> zapis na dysk) Używanie - z, aby zsynchronizować 2 katalogi na tym samym hoście, jest trochę głupie i marnowanie cykli procesora tak, jak byś je otrzymał (odczytaj dane z dysku -> kompresuj -> rozpakuj -> zapisz na dysk)
GerritCap

@GerritCap, dokonałem edycji, dzięki za cenny wkład
TuxForLife

1
Próbowałem tego polecenia, ale tworzy on podkatalog /home/user/B/Azamiast zastępować zawartość A treścią B. Czy mógłbyś mi pomóc to zobaczyć?
Łukasza

10

Możesz unisonopracować narzędzie opracowane przez Benjamina Pierce'a w U Penn.

Załóżmy, że masz dwa katalogi,

/home/user/Documents/dirA/ i /home/user/Documents/dirB/

Aby zsynchronizować te dwa, możesz użyć:

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

W wyniku unisonwyświetli każdy katalog i plik, który jest inny w dwóch katalogach, o które poprosiłeś o synchronizację. Zaleca się dodatkową synchronizację (replikację brakującego pliku w obu lokalizacjach) przy pierwszym uruchomieniu, a następnie utworzyć i utrzymywać drzewo synchronizacji na komputerze, a przy kolejnych uruchomieniach zaimplementuje prawdziwą synchronizację (tj. Jeśli usuniesz plik .../dirA, zostanie również usunięty .../dirB. Możesz także porównać każdą zmianę i opcjonalnie wybrać synchronizację do przodu lub do tyłu między dwoma katalogami.

Opcjonalnie, aby uruchomić interfejs graficzny, po prostu usuń -ui textopcję z polecenia, chociaż uważam, że jest to cliprostsze i szybsze w użyciu.

Więcej na ten temat: Samouczek Unison w dokumentacji użytkownika Unison .


1

Odpowiedź TuxForLife jest całkiem dobra, ale zdecydowanie sugeruję, abyś używał jej -cpodczas synchronizacji lokalnej. Możesz argumentować, że nie warto tracić czasu / kary sieciowej na zdalne synchronizacje, ale jest to całkowicie warte dla plików lokalnych, ponieważ prędkość jest tak duża.

-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.

To pokazuje, że posiadanie tego samego rozmiaru i znaczników czasu może Cię zawieść.

Ustawić

$ 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

Rsync, który niczego nie kopiuje, ponieważ wszystkie pliki mają ten sam rozmiar i znacznik czasu

$ 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    

Rsync, który działa poprawnie, ponieważ porównuje sumy kontrolne

$ 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

czy -c i -u działają dobrze razem?
Sergey Korzhov

@SergeyKorzhov robi. `-U 'nadal działa jak zwykle, aby aktualizować tylko wtedy, gdy miejsce docelowe nie jest nowsze.
Bruno Bronosky

1

To jest to, czego używam do tworzenia kopii zapasowych plików osobistych, gdzie nie dbam o wszystko objęte -ai chcę wydrukować więcej przydatnych informacji.

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

Ze strony man rsync :

-r, --recursive
Mówi rsync, aby rekurencyjnie kopiowało katalogi.

-t, --times
Mówi rsync, aby przesłał czasy modyfikacji wraz z plikami i zaktualizował je w systemie zdalnym.

-u, --update
Zmusza rsync do pominięcia wszystkich plików, które istnieją w miejscu docelowym i mają zmodyfikowany czas nowszy niż plik źródłowy. (Jeśli istniejący plik docelowy ma czas modyfikacji równy czasowi pliku źródłowego, zostanie zaktualizowany, jeśli rozmiary są różne).

--delete
Mówi rsync, aby usunęło niepotrzebne pliki ze strony odbierającej (te, które nie są po stronie wysyłającej), ale tylko dla synchronizowanych katalogów.

--info = FLAGI
Ta opcja umożliwia precyzyjną kontrolę nad wyświetlanymi informacjami, które chcesz zobaczyć.

Od 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)

Choć mniej wyraźne, wydaje się to równoważne i krótsze:

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

-v, --verbose
Pojedynczy -v poda informacje o przesyłanych plikach i krótkie podsumowanie na końcu [stats1].


0

Nie jest to całkowicie to samo, o co prosisz, ale możesz rozważyć użycie narzędzia do kontroli wersji. Narzędzia takie jak Git wykonują wszystko, o co prosisz, a nawet więcej, zwłaszcza jeśli nie pracujesz bezpośrednio w folderze B, interesujące może być spojrzenie na to. Więcej informacji na temat git można znaleźć tutaj


2
Działa to tylko wtedy, gdy chcesz dodać wszystko do kontroli wersji. Wymusza także, aby każda kiedykolwiek podjęta zmiana była trwale przechowywana, co może być niepożądane.
Qudit

@Qudit, to prawda, chociaż klonowanie pozwala ograniczyć historię, ale ograniczenie historii nie jest (jeszcze?) Domyślnie zaimplementowane w Git.
switch87

@ switch87 Tak, wiem, że możesz usunąć stare zatwierdzenia. Kontrola wersji nie jest jednak właściwym rozwiązaniem dla ogólnych kopii zapasowych imo, szczególnie jeśli są duże pliki binarne.
Qudit

Jego pytanie dotyczy lokalnej kopii zapasowej, ale jeśli użyjesz jej do zdalnej kopii zapasowej, nadal możesz użyć aneksu git dla większych plików. w przypadku lokalnej kopii zapasowej nie stanowi to problemu.
switch87

2
@ switch87 To naprawdę powinien być komentarz do Q, a nie odpowiedź, ponieważ nie wyjaśnia, jak używać git do robienia kopii zapasowych.
slm

0

Możesz użyć tego w następujący sposób:

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

W ten sposób skopiujesz zawartość folderu A do folderu B, a nie zawartość samego folderu A.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.