Как я могу легко подтвердить в Linux, что два отдельных каталога имеют одинаковое содержимое?

8

CentOS 5.x

Mq вопрос казался похожим на этот, но я не был уверен ...

У меня есть два сервера (полностью изолированных друг от друга), каждый с каталогом и подкаталогами, которые должны иметь одинаковое точное содержимое.

Например, макет каталога может быть примерно таким:

СЕРВЕР А -

/opt/foo/foob/1092380298309128301283/123.txt
/opt/foo/foob/5094380298309128301283/456.txt
/opt/foo/foob/5092380298309128301283/789.txt
/opt/foo/foob/1592380298309128301283/abc.txt

СЕРВЕР Б -

/opt/foo/foob/1092380298309128301283/123.txt
/opt/foo/foob/5094380298309128301283/456.txt
/opt/foo/foob/5092380298309128301283/789.txt
/opt/foo/foob/1592380298309128301283/abc.txt

В идеале я хотел бы сделать рекурсивную проверку и получить подтверждение того, что все совпадает.

Я также хочу избегать использования любых сторонних инструментов.

Любые идеи?

Майк Б
источник
Вы просто хотите сравнить две директории или сделать одну копию другой?
Скотт Пак
@ ScottPack Отличный вопрос. Я хочу сравнить, но НЕ вносить изменения. Что-то еще обрабатывает репликацию каталогов. Я просто хочу убедиться, что он делает свою работу.
Майк Б
1
Вы уже пометили этот вопрос rsync? Так ... хм, использовать rsync-nопцией)?
Мошенник
@faker Я думал, что rsync может быть вариантом, но я не был уверен, есть ли что-то лучше, проще или более специфично для этого варианта использования. Мне нужно знать, что имена файлов, дата, размер и относительное местоположение совпадают.
Майк Б
обратите внимание, что rsync не проверяет содержимое файла, если время и размер совпадают, см. параметр --checksum, если вас это беспокоит
рагу

Ответы:

9

Один хороший способ - использовать md5sums для каждого файла в дереве:

Запустите это на server1:

find /opt/foo/foob/ -type f -print0 | xargs -0 md5sum > report_from_server1.tx

Запустите это на server2

find /opt/foo/foob/ -type f -print0 | xargs -0 md5sum > report_from_server2.tx

Затем просто сравните два файла (используя diff) или что угодно.

Это то, что вы ищете?

Конечно, вы можете использовать SSH для удаленного выполнения команды, если хотите.

Камден С.
источник
Спасибо, Камден. Да, я думаю, это то, что я искал. Я проверю это и посмотрю, получится ли.
Майк Б
2
Или md5sum md5sums
dmourati
Отлично - верно, если вам не важно знать, какие файлы изменяются, вы можете просто md5sum получить результирующие файлы и сравнить эти две суммы.
Камден С.
Кроме того, вы, вероятно, уже знаете это, но для выполнения этой команды удаленно через SSH, вы просто должны сделатьssh user@servera 'find /opt/foo/foob/ -type f -print0 | xargs -0 md5sum'
Camden S.
1
MikeB, выполнив рекурсивный длинный листинг и передав его в md5sum, вы получите md5sum из списка каталогов, который исключит содержимое файлов. Если бы размеры inode в файловых системах на обоих концах были разными, это также могло бы создать разницу в размерах файлов. Создание md5sum для контента, как первоначально предложено @CamdenS. лучше.
около
7

Если вам не обязательно заботиться о том , что изменилось, просто что-то изменилось, rsync все еще действительно хорош для этого. Попробуйте выполнить эту команду и внимательно посмотреть на вывод, предполагая, что он запускается из «servera».

rsync -avcn /opt/foo/ serverb:/opt/foo

Результирующий список будет теми файлами, которые были бы изменены, если бы вы фактически запустили процесс синхронизации. Помните, что файлы будут отображаться в списке, даже если изменилась только временная метка, но содержимое осталось прежним. Поскольку мы добавили -nфлаг, то никакие действия фактически не будут выполняться, только сообщается.

Скотт Пак
источник
Спасибо. Что если две коробки полностью изолированы друг от друга? Как я могу использовать выходные данные для сравнения?
Майк Б
rsync не поддерживает удаленный источник и назначение, поэтому ему нужно будет запустить его на одном из своих серверов
faker
@faker: Должен признаться, никогда не пробовал это раньше, приятно знать. Как вы говорите, однако, это достаточно легко объяснить.
Скотт Пак
+1. Умное использование rsync. Тем не менее, чтобы быть полностью правильным, вам нужно запустить rsyncв обоих направлениях. То есть нужно добавить это:rsync -avcn serverb:/opt/foo/ /opt/foo
Стивен Понедельник
5

Несмотря на то, что вы могли бы собрать вместе быстрый скрипт, который будет вычислять отдельные хеши MD5 для отдельных файлов в каталоге, лучший способ сделать это - использовать инструмент под названием, md5deepкоторый будет рекурсивно вычислять хэши всех файлов в каталоге, а затем выводить их в файл. Затем его можно использовать в другом каталоге, взяв в качестве входных данных первый хеш-файл и предоставив вам список файлов, которые отличаются в двух каталогах.

Итак, взяв ваш пример, вы будете следовать этому процессу:

  1. Рассчитать хэши необходимого каталога на сервере A:

    md5deep -r /opt/foo/ > file_hashes.txt

  2. Скопируйте file_hashes.txtфайл на сервер B для сравнения.

  3. Рассчитайте хэши требуемого каталога на сервере B, но взяв хэши файлов с сервера A в качестве входного файла, используя -xфлаг, чтобы отображать только файлы, которые отличаются:

    md5deep -x file_hashes.txt -r /opt/foo/

Набор инструментов md5deep является частью системы управления пакетами большинства дистрибутивов, и замечательно то, что он поддерживает ряд различных алгоритмов хеширования, а не только MD5. Так что, если вы параноики по поводу столкновений, у вас есть ряд доступных альтернатив. Следующие инструменты являются частью md5deep, каждый из которых предоставляет альтернативный алгоритм хеширования:

   md5deep - Compute and compare MD5 message digests
   sha1deep - Compute and compare SHA-1 message digests
   sha256deep - Compute and compare SHA-256 message digests
   tigerdeep - Compute and compare Tiger message digests
   whirlpooldeep - Compute and compare Whirlpool message digests
Ричард Келлер
источник
0

Я использовал технику, похожую на @ scott-pack. Это скажет вам, что вы можете использовать двухстороннее расхождение. Все, что начинается с «удаления» - это файл, который находится на удаленном сервере, но не на локальном сервере. Каждый каталог, в котором нет содержимого файла, не содержит изменений. Каждый файл в списке - это файл, который либо не существует на удаленном сервере, либо локальная версия «новее».

rsync -rvnac --delete /local/directory/ user@remote:/remote/directory/
Дэвид Баукум
источник