Bash сравнить md5sum двух файлов

Обновлено: 07.07.2024

Программа md5sum не предоставляет контрольные суммы для каталогов. Я хочу получить единую контрольную сумму MD5 для всего содержимого каталога, включая файлы в подкаталогах. То есть одна объединенная контрольная сумма, сделанная из всех файлов. Есть ли способ сделать это?

Правильный путь зависит от того, почему вы спрашиваете:

Вариант 1. Сравнение только данных

Если вам просто нужен хеш содержимого файла дерева, это поможет:

Это сначала суммирует все содержимое файла индивидуально, в предсказуемом порядке, затем передает этот список имен файлов и хэшей MD5 для хеширования, давая единственное значение, которое изменяется только при изменении содержимого одного из файлов в дереве.

К сожалению, find -s работает только с BSD find (1), используемым в macOS, FreeBSD, NetBSD и OpenBSD. Чтобы получить что-то сопоставимое в системе с GNU или SUS find (1), вам нужно что-то более уродливое:

Мы заменили find -s на звонок sort . -k 2 Бит говорит это , чтобы пропустить через хэш MD5, поэтому он сортирует только имена файлов, которые находятся в поле 2 через конец-линии, по sort расчетам «s.

У этой версии команды есть недостаток, заключающийся в том, что она может запутаться, если у вас есть какие-либо имена файлов с символами новой строки в них, потому что она будет выглядеть как несколько строк в sort вызове. find -s Вариант не имеет этой проблемы, так как обход дерева и сортировка происходит в течение одной и той же программы, find .

В любом случае сортировка необходима, чтобы избежать ложных срабатываний: наиболее распространенные файловые системы Unix / Linux не поддерживают списки каталогов в стабильном, предсказуемом порядке. Вы можете не осознавать этого, используя ls и тому подобное, которое молча сортирует содержимое каталога для вас. find без -s или sort вызов собирается распечатать файлы в любом порядке, в котором их возвращает базовая файловая система, что приведет к тому, что эта команда выдаст измененное значение хеш-функции, если порядок файлов, переданных ей как входные, изменится

Возможно, вам придется изменить md5sum команды md5 или некоторые другие хэш-функции. Если вы выбираете другую хеш-функцию и вам нужна вторая форма команды для вашей системы, вам может потребоваться настроить sort команду соответствующим образом. Еще одна ловушка заключается в том, что некоторые программы суммирования данных вообще не записывают имя файла, основным примером является старая sum программа Unix .

Этот метод несколько неэффективен, вызывая md5sum N + 1 раз, где N - количество файлов в дереве, но это необходимая стоимость, чтобы избежать хэширования метаданных файла и каталога.

Вариант 2: сравнить данные и метаданные

Если вам необходимо определить, что изменилось что- либо в дереве, а не только содержимое файла, попросите tar упаковать содержимое каталога для вас, а затем отправьте его по адресу md5sum :

Поскольку tar он также определяет права доступа к файлам, владельца и т. Д., Он также обнаруживает изменения этих вещей, а не только изменения содержимого файла.

Этот метод значительно быстрее, так как он делает только один проход по дереву и запускает хэш-программу только один раз.

Как и в случае find описанного выше метода based, tar происходит обработка имен файлов в том порядке, в котором их возвращает базовая файловая система. Вполне может быть, что в вашем приложении вы можете быть уверены, что этого не произойдет. Я могу придумать, по крайней мере, три различных модели использования, где это может иметь место. (Я не собираюсь перечислять их, потому что мы попадаем на неопределенную область поведения. Здесь каждая файловая система может отличаться, даже от одной версии ОС к другой.)

Если вы обнаружите, что получаете ложные срабатывания, я бы рекомендовал find | cpio выбрать вариант ответа Жиля .

Я пытаюсь использовать md5sum для сравнения двух файлов в bash сценарий.

цель состоит в том, чтобы использовать .md5 одного файла, чтобы проверить md5sum другой файл. Мой поиск Google о том, как это сделать правильно, не показывает мне, как я это делаю. Запуск электронной почты работает, как и следовало ожидать. Теперь я пытаюсь заставить его запустить электронное письмо о неудаче, а не об успехе.

и, возможно, перечислите результат того, что было получено от .файл md5 и фактический md5sum поврежденного файла. Я разберусь с этим, в конце концов, но это несколько запутанно, так как я пытался понять, где я ошибаюсь здесь.

Shellcheck указывает, что код выглядит хорошо, но я не получаю результаты, которые я ожидаю получить.

несколько ссылок StackOverflow, которые я проверил, чтобы увидеть, может ли что-то работать:

вот содержание моего скрипт bash, в оригинальном виде:

обновлен код до следующего:

все еще работаю над этим. Все ближе к тому, чтобы это сработало!

Edit2: код теперь выглядит следующим образом, Также обратите внимание, что я удаляю GeoLiteCity2 и GeoLite, чтобы мы начали с новой загрузки баз данных каждый раз, когда MaxMind обновляет свою базу данных:

так .. проблема, которую вы видите, заключается в том, что формат вы создаете не соответствовать формату .md5 файл, который вы загружаете, против которого вам нужно проверить значение, которое вы вычисляете.

следующее Было бы ближе к моей версии сценария. (Пояснение ниже.)

основные различия здесь..

  • rm -f GeoLightCity.dat вместо -rf . Давай не будем заходить дальше, чем нужно. к.
  • md5sum принимает стандартный ввод, а не обработку файла по имени. Эффект заключается в том, что выходные данные не включают именем. К сожалению из-за ограничений в Linux md5sum command, это все еще не соответствует .md5 файл, который вы загружаете из Maxmind, так:
  • cut используется для изменения результирующего вывода, оставляя только вычисленный md5.
  • используя cmp вместо подоболочек, в комментарии на ваш вопрос.

второй и третий пункты являются, пожалуй, самым важным для вас.

еще один вариант для создания md5sum.txt файл будет делать это на лету, как вы скачать. Например:

использует tee команда для разделения файла на его местоположение "сохранить" и другой канал, который проходит через md5sum для создания вашего .txt-файл.

может сэкономить вам минуту, которая в противном случае будет съедена md5sum, который запускается позже. И это будет лучше использовать SMP. :)

В строке if [ $file1 != $file2 ] , вы не сравниваете содержимое двух файлов, а только имена файлов. Так что if [ "md5sum.txt" != "GeoLite2-City.md5" ] всегда будет верно.

Это должно работать:

для тех, кто приходит сюда, чтобы сравнить файл с определенной суммой md5, вы можете попробовать эту функцию:

Контрольная сумма - это цифра или строка, которая вычисляется путем суммирования всех цифр нужных данных. Ее можно использовать в дальнейшем для обнаружения ошибок в проверяемых данных при хранении или передаче. Тогда контрольная сумма пересчитывается еще раз и полученное значение сверяется с предыдущим.

В этой небольшой статье мы рассмотрим что такое контрольная сумма Linux, а также как выполнять проверку целостности файлов с помощью контрольных сумм md5.

Что такое MD5?

Контрольные суммы Linux с вычисляемые по алгоритму MD5 (Message Digest 5) могут быть использованы для проверки целостности строк или файлов. MD5 сумма - это 128 битная строка, которая состоит из букв и цифр. Суть алгоритма MD5 в том, что для конкретного файла или строки будет генерироваться 128 битный хэш, и он будет одинаковым на всех машинах, если файлы идентичны. Трудно найти два разных файла, которые бы выдали одинаковые хэши.

В Linux для подсчета контрольных сумм по алгоритму md5 используется утилита md5sum. Вы можете применять ее для проверки целостности загруженных из интернета iso образов или других файлов.

Эта утилита позволяет не только подсчитывать контрольные суммы linux, но и проверять соответствие. Она поставляется в качестве стандартной утилиты из набора GNU, поэтому вам не нужно ничего устанавливать.

Проверка контрольных сумм в Linux

Синтаксис команды md5sum очень прост:

$ md5sum опции файл

Опций всего несколько и, учитывая задачи утилиты, их вполне хватает:

Сначала скопируйте файл /etc/group в домашнюю папку чтобы на нем немного поэкспериментировать:

cp /etc/group groups

Например, давайте подсчитаем контрольную сумму для файла /etc/group:

md5

Или вы можете сохранить сразу эту сумму в файл для последующей проверки:

md5sum groups > groups.md5

Затем каким-либо образом измените этот файл, например, удалите первую строчку и снова подсчитайте контрольные суммы:

md51
md52

Как видите, теперь значение отличается, а это значит, что содержимое файла тоже изменилось. Дальше верните обратно первую строчку root:x:0: и скопируйте этот файл в groups_list и

cp groups groups_list

Затем опять должна быть выполнена проверка контрольной суммы linux:

md53

Сумма соответствует первому варианту, даже несмотря на то, что файл был переименован. Обратите внимание, что md5sum работает только с содержимым файлов, ее не интересует ни его имя, ни его атрибуты. Вы можете убедиться, что оба файла имеют одинаковые суммы:

md5sum groups groups_list

md54

md5sum groups groups_list > groups.md5

Чтобы проверить, не были ли файлы изменены с момента создания контрольной суммы используйте опцию -c или --check. Если все хорошо, то около каждого имени файла появится слово OK или ЦЕЛ:

md5sum -c groups.md5

md55

Но теперь вы не можете переименовывать файлы, потому что при проверке утилита будет пытаться открыть их по имени и, естественно, вы получите ошибку. Точно так же все работает для строк:

echo -n "Losst" | md5sum -
$ echo -n "Losst Q&A" | md5sum -

md56

Выводы

Из этой статьи вы узнали как выполняется получение и проверка контрольной суммы linux для файлов и строк. Хотя в алгоритме MD5 были обнаружены уязвимости, он все еще остается полезным, особенно если вы доверяете инструменту, который будет создавать хэши.

Проверка целостности файлов Linux - это очень важный аспект использования системы. Контрольная сумма файла Linux используется не только вручную при проверке загруженных файлов, но и во множестве системных программ, например, в менеджере пакетов. Если у вас остались вопросы, спрашивайте в комментариях!

На завершение небольшое видео по теме:

Итак, в основном, что я хочу сделать, это сравнить два файла за строкой по столбцу 2. Как я мог выполнить это?

Посмотрите на команду diff . Это хороший инструмент, и вы можете прочитать все об этом, введя man diff в свой терминал.

Команда, которую вы хотите сделать, это diff File_1.txt File_2.txt , которая выведет разницу между ними и будет выглядеть примерно так:

введите описание изображения здесь>> </p> <p> Быстрая заметка при чтении вывода из третьей команды: «стрелки» (<code>---- +: = 3 =: + ----</code> и <code>---- +: = 4 =: + ----</code>) ссылаются на то, что значение строки находится в левом файле (<code>---- +: = 5 =: + ----</code>) и правый файл (<code>---- +: = 6 =: + ----</code>), причем левым файлом является тот, который вы ввели первым в командной строке, в этом случае <code>---- +: = 7 = + ----</code> </p> <p> Кроме того, вы можете заметить, что 4-я команда - это <code>---- +: = 8 =: + ----</code>, которая передает результаты из <code>---- +: = 9 = : + ----</code> в <code>---- +: = 10 =: + ----</code>, который затем помещает этот вывод в файл, чтобы вы могли его сохранить для более позднего, если вы не хотите просматривать все это на консоли в эту секунду. </p></body></html>

Или вы можете использовать Meld Diff

Meld помогает сравнивать файлы, каталоги и контролируемую версию проекты. Он обеспечивает двух- и трехстороннее сравнение обоих файлов и каталогов и поддерживает многие популярные системы управления версиями.

Установите с помощью:

введите описание изображения здесь

введите описание изображения здесь>> </p> <p> Пример с полным текстом: </p> <p> <img src whoanswered

ответил Achu 25 августа 2014, 19:57:51

Вы можете использовать vimdiff .

Meld - отличный инструмент. Но вы также можете использовать diffuse для визуального сравнения двух файлов:

введите описание изображения здесь>> </p></body></html>

Скопируйте сценарий в пустой файл, сохраните его как compare.py , сделайте его исполняемым, запустите его командой:

С помощью нескольких дополнительных строк вы можете сделать это либо печатать на выходной файл, либо на терминал, в зависимости от того, установлен ли выходной файл:

Для печати в файл:

Для печати в окне терминала:

Вы можете использовать команду cmp :

FWIW, мне больше нравится то, что я получаю от бок о бок вывод из diff

даст что-то вроде:

Дополнительный ответ

Если вам не нужно знать, какие части файлов отличаются, вы можете использовать контрольную сумму файла. Существует много способов сделать это, используя md5sum или sha256sum

Рассмотрим сценарий ниже, где вы можете дать два файла в качестве аргументов, и файл скажет вам, являются ли они одинаковыми или нет.

Более старый ответ

Кроме того, существует команда comm , которая сравнивает два отсортированных файла и дает результат в 3-х столбцах: столбец 1 для элементов, уникальных для файл №1, столбец 2 для элементов, уникальных для файла № 2, и столбец 3 для элементов, присутствующих в обоих файлах.

Чтобы подавить любой столбец, вы можете использовать переключатели -1, -2 и -3. Использование -3 показывает линии, которые отличаются.

Ниже вы можете увидеть снимок экрана команды в действии.

введите описание изображения здесь

Существует только одно требование - файлы должны быть отсортированы для их надлежащего сопоставления. sort может использоваться для этой цели. Bellow - это еще один снимок экрана, где файлы сортируются, а затем сравниваются. Строки, начинающиеся с левого звонка только в File_1, строки, начинающиеся с столбца 2, принадлежат только File_2

введите описание изображения здесь>> </p></body></html>

Простым способом является использование colordiff , который ведет себя как diff , но окрашивает его вывод. Это очень полезно для чтения diff. Используя ваш пример,

, где опция u предоставляет унифицированный diff. Вот как выглядит раскрашенный diff:


Как найти два файла с совпадающими данными в сценарии оболочки и дубликат хранилища данных в другом файле оболочки?

Я написал код, но он не работал. Как это написать?

Чтобы просто проверить, совпадают ли два файла, используйте cmp -s :

Если ваши два входных файла содержит список путей файлов, которые вы хотите сравнить, используйте двойной цикл, например:

Здесь результат создается как на терминале, так и в файле file-comparison.out .

Предполагается, что ни один путь в двух входных файлах не содержит встроенных символов новой строки.

Код сначала считывает все пути из одного из файлов в массив, files1 , с помощью mapfile . Я делаю это, чтобы не читать этот файл более одного раза, так как нам придется просматривать все эти пути для каждого пути в другом файле. Вы заметите, что вместо чтения из $filelist1 во внутреннем цикле я просто перебираю имена в files1 массив.

  • мне нужна полная программа в оболочке bash
  • @santhoshreddy См. обновленный ответ.

Самый простой способ - использовать команду diff .

пример:

предположим, что первый файл file1.txt и он содержит:

и второй файл file2.txt

тогда мы можем использовать команду diff для автоматического отображения строк, различающихся в двух файлах:

diff file1.txt file2.txt

Давайте посмотрим, что означает этот вывод. Важно помнить, что когда diff описывает вам эти различия, он делает это в предписывающем контексте: он сообщает вам, как изменить первый файл, чтобы он соответствовал второму файлу. Первая строка вывода diff будет содержать:

  • номера строк, соответствующие первому файлу,
  • буква (a для добавления, c для изменения или d для удаления)
  • номера строк, соответствующие второму файлу.

Вот чистый сценарий оболочки bash для сравнения файлов:

Комментарии к конкретным командам можно удалить, чтобы выйти при первом обнаруженном различии и, если вы хотите, увидеть каждую прочитанную строку.

Читайте также: