Як синхронізувати дві папки з інструментами командного рядка?


63

Перемістившись на Linux з Windows, я хотів би знайти альтернативне програмне забезпечення для Winmerge, а точніше навчитися інструментам командного рядка для порівняння та синхронізації двох папок в Linux. Буду вдячний, якби ви могли сказати мені, як виконувати наступні завдання в командному рядку ... (Я вивчив діф та rsync, але мені ще потрібна допомога.)

У нас є дві папки: "/ home / user / A" і "/ home / user / B"

Папка А - це місце, де зберігаються звичайні файли та папки, а папка В - це резервна папка, яка служить повним дзеркалом папки А. (Ніщо безпосередньо не зберігає та не змінює користувач у папці B.)

Мої запитання:

  • Як перелічити файли, які існують лише у папці B? (Наприклад, видалені з папки А після останньої синхронізації.)

  • Як скопіювати файли, які існують лише в папці B назад, у папку A?

  • Як перелічити файли, які існують в обох папках, але мають різні часові позначки або розміри? (Ті, які були змінені в папці А з часу останньої синхронізації. Я хотів би уникати використання контрольних сум, оскільки є десятки тисяч файлів, і це зробить процес занадто повільним.)

  • Як зробити точну копію папки А в папку B? Я маю на увазі, скопіюйте все з папки А в папку B, яка існує тільки в папці A, і видаліть все з папки B, яка існує лише в папці B, але не торкаючись файлів, однакових в обох папках.


Чому б не використовувати для цього належну програму резервного копіювання? Подвійність - один із прикладів.
Кудит

Відповіді:


88

Це додає папку A у папку B:

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

Якщо ви хочете, щоб вміст папок A і B був однаковим, поставте /home/user/A/(з косою рисою) як джерело. Це забирає не папку А, а весь її вміст і поміщає її в папку B. Приблизно так:

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a Виконайте синхронізацію, зберігаючи всі атрибути файлової системи
  • -v бігати багатослівно
  • -u копіюйте файли лише з новішим часом модифікації (або різницею розмірів, якщо час однаковий)
  • --delete видаліть файли в цільовій папці, які не існують у джерелі

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


7
rsync : запустити додаток rsync, -a : виконати синхронізацію, зберігаючи всі атрибути файлової системи, -v : запустити докладно, -z : стиснути дані під час синхронізації (транспортувати дані у стисненому режимі), - видалити : видалити файли в цільовому режимі папка, яка не існує у вихідному коді, / home / user / A : папка source, / home / user / B : цільова папка
SonicARG

Привіт SonicARG, я зовсім забув повернутися до цього і поставив пояснення, дякую, подавши пояснення, я поставив ваше у відповідь, сподіваюся, ви не заперечуєте.
TuxForLife

6
Rsync призначений в основному для копіювання файлів між різними комп'ютерами, як пояснено тут, це може служити і для синхронізації каталогів. Тож варіант -z цікавий для зменшення мережевого трафіку і, таким чином, для підвищення продуктивності rsync між двома комп’ютерами: (читання даних з диска -> стиснення) === мережа ===> (скасування -> запис на диск) Використання - z синхронізувати 2 каталоги на одному хості - це трохи нерозумно і марно витрачати цикли процесора, як ви отримали (читати дані з диска -> стискати -> розтискати -> записувати на диск)
GerritCap

@GerritCap, я вніс редагування, дякую за ваш цінний внесок
TuxForLife

1
Я спробував команду, але вона створила суб-редактор /home/user/B/Aзамість того, щоб перезаписати вміст A на вміст B. Не могли б ви допомогти мені подивитися на це?
Лук,

10

Ви можете використати unisonінструмент, розроблений Бенджаміном Пірсом в U Penn.

Припустимо, у вас є два каталоги,

/home/user/Documents/dirA/ і /home/user/Documents/dirB/

Щоб синхронізувати ці два, ви можете використовувати:

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

На виході unisonвідображатиметься кожен каталог і файл, який відрізняється в двох каталогах, які ви просили синхронізувати. Він рекомендує додатково синхронізувати (копіювати відсутні файли в обох місцях) на початковому запуску, потім створити та підтримувати дерево синхронізації на вашій машині, а на наступних запусках реалізувати справжню синхронізацію (тобто, якщо ви видалите файл із .../dirAнього, він .../dirBВи також будете видалені з них . Ви також можете порівняти кожну зміну та, за бажанням, вибрати переадресацію чи зворотну синхронізацію між двома каталогами.

За бажанням, щоб запустити графічний інтерфейс, просто видаліть -ui textопцію зі своєї команди, хоча я вважаю cliпростішим і швидшим у використанні.

Детальніше про це: Підручник Unison в документації користувача Unison .


1

Відповідь TuxForLife досить хороший, але я настійно пропоную вам використовувати -cпід час синхронізації локально. Ви можете стверджувати, що не варто штрафувати час / мережу, робити це для віддалених синхронізацій, але це повністю варто для локальних файлів, оскільки швидкість така велика.

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

Це показує, як однакові розміри та часові позначки можуть зірвати вас.

Установка

$ 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, яка нічого не копіює, оскільки всі файли мають однаковий розмір та часову позначку

$ 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 працює правильно, оскільки порівнює контрольні суми

$ 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 і -u добре працюють разом?
Сергій Коржов

@SergeyKorzhov це робить. '-U' як і раніше працює, як правило, для оновлення, лише якщо пункт призначення не є новішим.
Бруно Броноський

1

Це те, що я використовую для резервного копіювання особистих файлів, де мені не байдуже все, що охоплюється -a, і хочу надрукувати більше корисної інформації.

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

З сторінки man rsync :

-r, --рекурсивна
Це вказує rsync копіювати каталоги рекурсивно.

-t, --times
Це говорить rsync про перенесення змін моди разом з файлами та оновлення їх у віддаленій системі.

-u, --update
Це змушує rsync пропускати будь-які файли, які існують у пункті призначення, і мають модифікований час, який є новим, ніж вихідний файл. (Якщо в існуючому файлі призначення є час модифікації, рівний до вихідного файлу, він буде оновлений, якщо розміри різні.)

--delete
Це вказує rsync видаляти сторонні файли з боку прийому (ті, які не перебувають на стороні надсилання), але лише для каталогів, які синхронізуються.

--info = ФЛАГИ
Цей параметр дозволяє вам здійснювати тонкий контроль над інформацією, яку ви хочете бачити.

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

Хоча це менш явно, це, здавалося б, рівнозначно і коротше:

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

-v, --verbose
Single -v дасть вам інформацію про файли, що передаються, та короткий підсумок в кінці [stats1].


0

Це не зовсім те саме, що ви просите, але ви можете розглянути можливість використання інструменту контролю версій. Такі інструменти, як Git, роблять все, що вам потрібно, і багато іншого, особливо якщо ви не працюєте безпосередньо в папці B, це може бути цікаво поглянути на це. ви можете знайти більше інформації про git тут


2
Це працює лише в тому випадку, якщо ви готові додати все до контролю версій. Це також змушує будь-яку зміну, яку-небудь вчиняти, постійно зберігати, що може бути небажаним.
Кудит

@Qudit, це правда, хоча за допомогою клонування можна обмежити історію, але обмеження історії не (ще?) Реалізовано в Git за замовчуванням.
switch87

@ switch87 Так, я знаю, що ви можете видалити старі файли. Контроль версій насправді не є підходящим рішенням для загальних резервних копій imo, особливо якщо є великі бінарні файли.
Кудит

Його питання стосується локальної резервної копії, але якщо ви використовуєте її для віддаленого резервного копіювання, ви все одно можете використовувати git-додаток для великих файлів. для локальної резервної копії це не проблема.
switch87

2
@ switch87 Це дійсно повинно бути коментарем до Q, а не відповіддю, оскільки це не пояснює, як ви використовували Git для створення резервних копій.
slm

0

Ви можете використовувати його таким чином:

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

Таким чином ви скопіюєте вміст папки A у папку B, а не сам папку A.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.