Как я получаю сумму MD5 содержания каталога как одна сумма?

Я уверен, что существует миллион способов сделать это, но я использовал 'vconfig' для добавления VLAN в прошлом.

Сначала добавьте VLAN
'vconfig добавляют eth0 123'

Теперь можно настроить интерфейс sub
'ifconfig eth0.123...'

178
05.04.2012, 22:48
18 ответов

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

Опция 1: сравните данные только

Если Вам просто будет нужен хеш содержания файла дерева, то это добьется цели:

$ find -s somedir -type f -exec md5sum {} \; | md5sum

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

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

$ find somedir -type f -exec md5sum {} \; | sort -k 2 | md5sum

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

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

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

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

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

Опция 2: сравните данные и метаданные

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

$ tar -cf - somedir | md5sum

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

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

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

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

206
27.01.2020, 19:27
  • 1
    я думаю, лучше перейти к сравниваемому каталогу и использование find . вместо find somedir. Таким образом, имена файлов являются тем же, чтобы обеспечение различных спецификаций пути нашло; это может быть хитрым :-) –  Abbafei 24.06.2014, 09:50
  • 2
    Действительно ли мы должны отсортировать файлы также? –  CMCDragonkai 19.01.2016, 04:52
  • 3
    @CMCDragonkai:Что Вы имеете в виду? в первом случае мы действительно сортируем список имен файлов. Во втором случае мы намеренно делаем, не потому что часть подчеркнутого, который что-либо в первом предложении - то, что порядок файлов в каталоге изменился, таким образом, Вы не хотели бы сортировать что-либо. –  Warren Young 19.01.2016, 05:45
  • 4
    @WarrenYoung можно ли объяснить тщательнее, почему опция 2 не всегда лучше? Это, кажется, является более быстрым, более простым и более межплатформенным. В этом случае разве это не должна быть опция 1? –  Robin Winslow 17.08.2016, 10:51
  • 5
    : find somedir -type f -exec sh -c "openssl dgst -sha1 -binary {} | xxd -p" \; | sort | openssl dgst -sha1 для игнорирования всех имен файлов (должен работать с новыми строками) –  windm 22.10.2017, 12:50

Я использую этот свой отрывок для умеренных объемов:

find . -xdev -type f -print0 | LC_COLLATE=C sort -z | xargs -0 cat | md5sum -

и этот для XXXL:

find . -xdev -type f -print0 | LC_COLLATE=C sort -z | xargs -0 tail -qc100 | md5sum -

2
27.01.2020, 19:27
  • 1
    Что делает -xdev флаг делает? –  czerasz 04.05.2017, 09:35
  • 2
    Это призывает, чтобы Вы ввели: man find и читайте что прекрасный ручной ;) –  poige 04.05.2017, 15:43
  • 3
    :-). -xdev Don't descend directories on other filesystems. –  czerasz 04.05.2017, 19:31

Если Ваша цель состоит в том, чтобы только найти различия между двумя каталогами, рассмотрите использование различный.

Попробуйте это:

diff -qr dir1 dir2
9
27.01.2020, 19:27
  • 1
    Да, это полезно также. Я думаю, что Вы имели в виду dir1 dir2 в той команде. –   06.04.2012, 20:35
  • 2
    я обычно не использую графический интерфейсы пользователя, когда я могу избежать их, но для каталога diffing kdiff3, является большим и также работает над многими платформами. –  sinelaw 17.04.2012, 05:21
  • 3
    Об Отличающихся файлах сообщают также с этой командой. –  Serge Stroobandt 02.04.2014, 18:02

Взгляните на md5deep. Некоторые функции md5deep, который может заинтересовать Вас:

Рекурсивная операция - md5deep может к рекурсивному, исследуют все дерево каталогов. Таким образом, вычислите MD5 для каждого файла в каталоге и для каждого файла в каждом подкаталоге.

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

...

13
27.01.2020, 19:27
  • 1
    Хороший, но не может заставить это работать, говорит это .../foo: Is a directory, что дает? –  Camilo Martin 02.10.2014, 04:21
  • 2
    Самостоятельно md5deep не решает проблему OP, поскольку это не печатает объединенный md5sum, это просто печатает md5sum для каждого файла в каталоге. Тем не менее Вы можете md5sum вывод md5deep - не совсем, что требуемый OP, но близко! например, для текущего каталога: md5deep -r -l -j0 . | md5sum (где -r является рекурсивным, -l означает "относительные пути использования" так, чтобы полный путь файлов не вмешивался при попытке сравнить содержание двух каталогов, и -j0 средства используют 1 поток для предотвращения недетерминизма из-за индивидуума md5sums, возвращаемого в различных заказах). –  Stevie 14.10.2015, 15:34
  • 3
    Как проигнорировать некоторые файлы/каталоги в пути? –  Sandeepan Nath 21.10.2016, 16:17

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

Данные и метаданные

Создание архива, содержащего файлы, является хорошим началом. Это - однозначное представление (очевидно, так как можно восстановить файлы путем извлечения архива). Это может включать метаданные файла, такие как даты и владение. Однако это еще не совершенно правильно: архив неоднозначен, потому что его представление зависит от порядка, в котором файлы хранятся, и если применимо на сжатии.

Решение состоит в том, чтобы отсортировать имена файлов прежде, чем заархивировать их. Если Ваши имена файлов не содержат новые строки, можно работать find | sort перечислить их и добавить их к архиву в этом порядке. Всего хорошего, чтобы сказать archiver не рекурсивно вызывать в каталоги. Вот примеры с POSIX pax, Tar GNU и cpio:

find | LC_ALL=C sort | pax -w -d | md5sum
find | LC_ALL=C sort | tar -cf - -T - --no-recursion | md5sum
find | LC_ALL=C sort | cpio -o | md5sum

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

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

{ export LC_ALL=C;
  find -type f -exec wc -c {} \; | sort; echo;
  find -type f -exec md5sum {} + | sort; echo;
  find . -type d | sort; find . -type d | sort | md5sum;
} | md5sum

Мы включаем список каталогов в дополнение к списку контрольных сумм, поскольку в других отношениях пустые каталоги были бы невидимы. Список файлов отсортирован (в определенной, восстанавливаемой локали — благодаря Peter. O для напоминания мне этого). echo разделяет эти две части (без этого, Вы могли сделать некоторые пустые каталоги, на имя которых похожи md5sum вывод, который мог также передать для обычных файлов). Мы также включаем список размеров файла, для предотвращения дополнительных длиной нападений.

Между прочим, MD5 удерживается от использования. Если это доступно, рассмотрите использование SHA-2 или по крайней мере SHA-1.

Имена и данные, поддерживая новые строки на имена

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

{ export LC_ALL=C;
  du -0ab | sort -z; # file lengths, including directories (with length 0)
  echo | tr '\n' '\000'; # separator
  find -type f -exec sha256sum {} + | sort -z; # file hashes
  echo | tr '\n' '\000'; # separator
  echo "End of hashed data."; # End of input marker
} | sha256sum

Более устойчивый подход

Вот минимально протестированный сценарий Python, который создает хеш, описывающий иерархию файлов. Это берет каталоги и содержание файла в учетные записи и игнорирует символьные ссылки и другие файлы, и возвращает фатальную ошибку, если какой-либо файл не может быть считан.

#! /usr/bin/env python
import hashlib, hmac, os, stat, sys
## Return the hash of the contents of the specified file, as a hex string
def file_hash(name):
    f = open(name)
    h = hashlib.sha256()
    while True:
        buf = f.read(16384)
        if len(buf) == 0: break
        h.update(buf)
    f.close()
    return h.hexdigest()
## Traverse the specified path and update the hash with a description of its
## name and contents
def traverse(h, path):
    rs = os.lstat(path)
    quoted_name = repr(path)
    if stat.S_ISDIR(rs.st_mode):
        h.update('dir ' + quoted_name + '\n')
        for entry in sorted(os.listdir(path)):
            traverse(h, os.path.join(path, entry))
    elif stat.S_ISREG(rs.st_mode):
        h.update('reg ' + quoted_name + ' ')
        h.update(str(rs.st_size) + ' ')
        h.update(file_hash(path) + '\n')
    else: pass # silently symlinks and other special files
h = hashlib.sha256()
for root in sys.argv[1:]: traverse(h, root)
h.update('end\n')
print h.hexdigest()
39
27.01.2020, 19:27
  • 1
    OK, это работает, спасибо. Но есть ли какой-либо способ сделать это без включения каких-либо метаданных? Прямо сейчас мне нужен он для просто фактического содержания. –   06.04.2012, 04:12
  • 2
    Как насчет LC_ALL=C sort для проверки от различных сред... (+1 btw) –  Peter.O 06.04.2012, 09:16
  • 3
    Вы сделали целую программу Python для этого?Спасибо! Это - действительно больше, чем, что я ожидал.:-) Так или иначе я проверю эти методы, а также новую опцию 1 Warren. –   06.04.2012, 20:33
  • 4
    Хороший ответ. Установка порядка сортировки с LC_ALL=C важно при работе нескольких машин и oss –  Davor Cubranic 03.08.2016, 23:52
  • 5
    , Что делает cpio -o - средний? Не использование cpio stdin/out по умолчанию? GNU cpio 2.12 производит cpio: Too many arguments –  Jan Tojnar 12.08.2016, 15:40

Содержание файла только, исключая имена файлов

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

Эта версия (ответ Warren Young) помогла много, но моей версии md5sum производит имя файла (относительно пути, я выполнил команду от), и имена папок отличались, поэтому даже при том, что отдельные контрольные суммы файла соответствовали, заключительная контрольная сумма не сделала.

Для фиксации этого, в моем случае, я просто должен был снять изоляцию с имени файла от каждой строки find вывод (выбирают только первое слово, как разделено использованием пробелов cut):

find -s somedir -type f -exec md5sum {} \; | cut -d" " -f1 | md5sum
3
27.01.2020, 19:27
  • 1
    Вы, возможно, должны были бы отсортировать контрольные суммы также для получения восстанавливаемого списка. –  eckes 22.03.2016, 23:34

Хорошая древовидная контрольная сумма является древовидным идентификатором Мерзавца.

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

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

2
27.01.2020, 19:27

Я не хотел новых исполняемых файлов, ни Clunky Solutions, поэтому вот мой взять:

#!/bin/sh
# md5dir.sh by Camilo Martin, 2014-10-01.
# Give this a parameter and it will calculate an md5 of the directory's contents.
# It only takes into account file contents and paths relative to the directory's root.
# This means that two dirs with different names and locations can hash equally.

if [[ ! -d "$1" ]]; then
    echo "Usage: md5dir.sh <dir_name>"
    exit
fi

d="$(tr '\\' / <<< "$1" | tr -s / | sed 's-/$--')"
c=$((${#d} + 35))
find "$d" -type f -exec md5sum {} \; | cut -c 1-33,$c- | sort | md5sum | cut -c 1-32
1
27.01.2020, 19:27

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

> md5deep -r -l . | sort | md5sum
d43417958e47758c6405b5098f151074 *-

md5deep не требуется.

7
27.01.2020, 19:27

решение:

$ pip install checksumdir
$ checksumdir -a md5 assets/js
981ac0bc890de594a9f2f40e00f13872
$ checksumdir -a sha1 assets/js
88cd20f115e31a1e1ae381f7291d0c8cd3b92fad

работает быстро и проще решение, чем bash скриптинг.

см. док: https://pypi.python.org/pypi/checksumdir/1.0.5

5
27.01.2020, 19:27

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

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

fingerprint analyze

Это сгенерирует index.fingerprint в текущем каталоге, который включает контрольные суммы, имена и размеры файлов. По умолчанию он использует как MD5 , так и SHA1.256 .

В будущем я надеюсь добавить поддержку Merkle Trees в Fingerprint, что даст вам единую контрольную сумму верхнего уровня. Прямо сейчас вам нужно сохранить этот файл для проверки.

1
27.01.2020, 19:27

nix-hash из менеджера пакетов Nix

Команда nix-hash вычисляет криптографический хэш содержимого каждого пути и выводит его на стандартный вывод. По умолчанию она вычисляет хэш MD5, но доступны и другие алгоритмы хэширования. Хэш выводится в шестнадцатеричном формате.

Хеш вычисляется над сериализацией каждого пути: дампом дерева файловой системы, корнем которого является путь. Это позволяет каталогам и симлинки могут быть хэшированы а также обычные файлы. Дамп имеет формат NAR, создаваемый nix-store --dump. Таким образом, nix-hash path дает такой же криптографический хэш, что и nix-store --dump path | md5sum.

3
27.01.2020, 19:27

Делаем индивидуально для всех файлов в каждой директории.

# Calculating
find dir1 | xargs md5sum > dir1.md5
find dir2 | xargs md5sum > dir2.md5
# Comparing (and showing the difference)
paste <(sort -k2 dir1.md5) <(sort -k2 dir2.md5) | awk '$1 != $3'
0
27.01.2020, 19:27

Если вам не нужен md5, вы можете попробовать

find. -type f | xargs cksum | cksum
0
27.01.2020, 19:27

В дополнение к -до этого отличного ответа , если вы хотите ускорить вычисление контрольной суммы для большого каталога, попробуйте GNU Parallel:

find -s somedir -type f | parallel -k -n 100 md5 {} | md5

(Используется Mac с md5, замените при необходимости.)

Флаг -kважен, он указывает parallelподдерживать порядок, иначе общая сумма может измениться от запуска к запуску, даже если все файлы одинаковы. -n 100говорит запускать каждый экземпляр md5со 100 аргументами, это параметр, который вы можете настроить для лучшего времени выполнения. См. также флаг -Xиз parallel(, хотя в моем личном случае это вызвало ошибку.)

4
27.01.2020, 19:27

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

cd /path/to/dir; ls -lnAR --time-style=+%s. | md5sum

Если вы также хотите отслеживать изменения в расширенных атрибутах:

cd /path/to/dir; (ls -lnAR --time-style=+%s.; getfacl -Rns.) | md5sum

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

Примечания:

  • cd /path/to/dir -делает контрольную сумму устойчивой к перемещению каталога
  • -n -делает контрольную сумму постоянной в системах с различным отображением uid/gid
  • -A -включает все файлы, включая (с точками, такие как -a ), кроме. и..
  • --time -style=+%s -без него изменения, сделанные в течение 1 минуты после внесения контрольной суммы, могут остаться неотслеживаемыми, этот вывод также сохраняется между копиями rsync (в отличие от --full -опция времени)

Если вы все еще хотите проверять содержимое файлов:tar c -C /path/to/dir | md5sumили с расширенными атрибутами:cd /path/to/dir; (tar c.; getfacl -Rns.) | md5sum

Обновление:

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

cd /path;LC_ALL=C ls -lnAR --time-style=+%s.|awk '{$2=0;$1~/^d/&&$5=0;print}'|md5sum
0
27.01.2020, 19:27

На данный момент самый быстрый способ сделать это — использовать tar. А с помощью нескольких дополнительных параметров мы также можем избавиться от разницы, вызванной метаданными.

Чтобы использовать tar для хеширования каталога, нужно убедиться, что вы сортируете путь во время tar, иначе он всегда будет другим.

tar -C <root-dir> -cf - --sort=name <dir> | sha256sum

игнорировать время

Если вас не волнует время доступа или время изменения, также используйте что-то вроде --mtime='UTC 2019-01-01' , чтобы убедиться, что все метки времени одинаковы.

игнорировать права собственности

Обычно нам нужно добавить --group=0 --owner=0 --numeric-owner, чтобы унифицировать метаданные владельца.

игнорировать некоторые файлы

использовать--exclude=PATTERN

1
26.10.2020, 15:45

Если у вас установлен Python 3 с pip, вы можете использовать для этого мой пакет pyfstools . Быстрое использование:

$ pip install git+https://github.com/sorgloomer/pyfstools.git@main
...
$ python -m pyfstools hash --algo md5.
dir 88c17b149c1d9fef50f642b698cef9e6
0
06.12.2020, 03:36

Теги

Похожие вопросы