проверить идентичность (рекурсивной) копии каталога

356
A. Donda

Иногда мне приходится копировать / синхронизировать большие объемы данных в структуре каталогов с одного компьютера на другой. Типичными программами, которые я использую для этой цели, являются rsync, syncthing или seafile.

Чтобы не полагаться исключительно на правильность программы копирования / синхронизации (или выбранных мной опций), я обычно генерирую файл контрольной суммы (используя cfv) в родительском каталоге и копирую / синхронизирую его с данными, чтобы впоследствии я мог проверить все на конечном компьютере в порядке. Например, cfvхорошо работает, чтобы увидеть, все ли файлы из источника благополучно прибыли.

Однако я пропускаю один из вариантов, чтобы посмотреть, есть ли в копии файлы, которых не было в оригинале. Насколько я могу сказать, cfvнет возможности искать такие «дополнительные» файлы. Решение, к которому я прибегаю, состоит в том, чтобы создать новый файл контрольной суммы для копии и сравнить его с оригиналом, но это означает, что контрольные суммы для каждого файла должны быть вычислены четыре раза (создание и проверка на обоих компьютерах).

Есть ли лучшее решение?

0

1 ответ на вопрос

2
Kamil Maciorowski

Вычисление контрольных сумм выглядит для меня излишним, если вы хотите обнаружить только «дополнительные» файлы. Вам не нужно проверять фактические данные (содержимое файла); вам нужно проверить метаданные (существующие пути).

Чтобы получить все относительные пути внутри /synced/dir, запустите

(cd /synced/dir && find . | sort) > structure.txt 

Делайте это с обеих сторон, затем diffполучайте файлы. Обратите внимание, что ситуация симметрична, поэтому вы обнаружите «дополнительные», а также «отсутствующие» файлы на любой стороне («дополнительные» здесь эквивалентны «отсутствующим» там, и наоборот).

Чтобы игнорировать «дополнительные» файлы с одной (или другой) стороны, отфильтруйте diffвывод с помощью grep '^>'(или grep '^<'соответственно).

Если две директории доступны (смонтированы) в одной системе, этот синтаксис Bash может быть полезен:

diff <(cd /original/dir && find . | sort) <(cd /backup/dir && find . | sort) | grep '^>' 

Это не совсем надежно (например, переводы строк в именах файлов могут нарушить логику), мой пример более похож на доказательство концепции. Дело в том, что вы обнаруживаете дополнительные файлы, не читая содержимое файла вообще.

Заметки:

  • sortнеобходим, потому что эти два findмогут возвращать записи в различной последовательности, даже если каталоги являются точными копиями;
  • sole diffможет сравнивать каталоги, но этот режим здесь бесполезен, потому что он пытается сравнить содержимое соответствующих файлов, такого поведения мы хотим избежать в первую очередь.
Спасибо! И извините, что принял, а затем и не принял, но ваш ответ вдохновил меня, как сделать это еще более упорядоченным. Смотри мой ответ. A. Donda 5 лет назад 0