Как синхронизировать две папки с помощью инструментов командной строки?


63

Перейдя на Linux из Windows, я хотел бы найти альтернативное программное обеспечение для Winmerge или, скорее, изучить инструменты командной строки для сравнения и синхронизации двух папок в Linux. Я был бы признателен, если бы вы сказали мне, как выполнять следующие задачи в командной строке ... (Я изучал diff и rsync, но мне все еще нужна помощь.)

У нас есть две папки: "/ home / user / A" и "/ home / user / B"

Папка A - это место, где хранятся обычные файлы и папки, а папка B - это папка резервной копии, которая служит полным зеркалом папки A. (Пользователь ничего не сохраняет и не изменяет непосредственно в папке B.)

Мои вопросы:

  • Как перечислить файлы, которые существуют только в папке B? (Например, те, которые были удалены из папки A с момента последней синхронизации.)

  • Как скопировать файлы, которые существуют только в папке B, обратно в папку A?

  • Как составить список файлов, которые существуют в обеих папках, но имеют разные временные метки или размеры? (Те, которые были изменены в папке A с момента последней синхронизации. Я хотел бы избежать использования контрольных сумм, потому что есть десятки тысяч файлов, и это сделало бы процесс слишком медленным.)

  • Как сделать точную копию папки A в папку B? Я имею в виду, скопируйте все из папки A в папку B, которая существует только в папке A, и удалите все из папки B, которая существует только в папке B, но не касаясь файлов, которые являются одинаковыми в обеих папках.


Почему бы не использовать правильную программу резервного копирования для этого? Двуличность - один из примеров.
Кудит

Ответы:


88

Это помещает папку A в папку B:

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

Если вы хотите, чтобы содержимое папок A и B было одинаковым, поместите /home/user/A/(с косой чертой) в качестве источника. Это берет не папку 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 : сжать данные во время синхронизации (транспортировать данные в сжатом режиме), --delete : удалить файлы в целевой папке папка, которой нет в источнике, / home / user / A : исходная папка, / home / user / B : целевая папка
SonicARG

Привет SonicARG, я полностью забыл вернуться к этому и поставить объяснение, спасибо, отправив объяснение, я поставил ваш ответ, надеюсь, вы не возражаете.
TuxForLife

6
Rsync в первую очередь предназначен для копирования файлов между различными компьютерами, как объясняется здесь, он также может использоваться для синхронизации каталогов. Таким образом, опция -z интересна для уменьшения сетевого трафика и, следовательно, для повышения производительности rsync между двумя компьютерами: (чтение данных с диска -> сжатие) === сеть ===> (распаковка-> запись на диск) Использование - z Синхронизация 2 каталогов на одном и том же хосте немного глупа и тратит впустую циклы процессора (чтение данных с диска -> сжатие -> распаковка -> запись на диск)
GerritCap

@GerritCap, я внес изменения, спасибо за ваш ценный вклад
TuxForLife,

1
Я пробовал команду, но она создала вспомогательный каталог /home/user/B/Aвместо того, чтобы перезаписывать содержимое A на содержимое B. Не могли бы вы помочь мне взглянуть на это?
Люк

11

Вы могли бы 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>"

Со страницы руководства rsync :

-r, --recursive Указывает
rsync рекурсивно копировать каталоги.

-t, --times
Это указывает rsync передавать время модификации вместе с файлами и обновлять их в удаленной системе.

-u, --update
Это заставляет rsync пропускать любые файлы, которые существуют в месте назначения и имеют измененное время, которое является более новым, чем исходный файл. (Если существующий конечный файл имеет время модификации, равное времени исходного файла, оно будет обновлено, если размеры будут другими.)

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

--info = FLAGS
Эта опция позволяет вам детально контролировать вывод информации, которую вы хотите увидеть.

Из 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
Один -v даст вам информацию о том, какие файлы передаются, и краткую сводку в конце [stats1].


0

Это не совсем то, что вы просите, но вы могли бы рассмотреть возможность использования инструмента контроля версий. Такие инструменты, как Git, делают все, что вы просите, и даже больше, особенно если вы не работаете в папке B напрямую, было бы интересно взглянуть на это. Вы можете найти больше информации о git здесь


2
Это работает, только если вы готовы добавить все в систему контроля версий. Это также заставляет каждое изменение, когда-либо совершенное, быть сохраненным навсегда, что может быть нежелательным.
Кудит

@Qudit, это правда, хотя с помощью клонирования можно ограничить историю, но ограничение истории еще не реализовано в Git по умолчанию.
switch87

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

Его вопрос касается локального резервного копирования, но если вы используете его для удаленного резервного копирования, вы все равно можете использовать git annex для больших файлов. для локального резервного копирования это не проблема.
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.