Как я могу вычислить контрольную сумму md5 в каталоге? - программирование

Как я могу вычислить контрольную сумму md5 в каталоге?

Мне нужно вычислить сводную контрольную сумму md5 для всех файлов определенного типа (например, *.py), помещенных под каталог и все подкаталоги.

Каков наилучший способ сделать это?

Изменить: Предлагаемые решения очень приятные, но это не совсем то, что мне нужно. Я ищу решение для получения контрольной суммы single summary, которая однозначно идентифицирует каталог в целом, включая содержимое всех его подкаталогов.

4b9b3361

Ответ 1

find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum

Команда find отображает все файлы, которые заканчиваются на .py. Md5sum вычисляется для каждого .py файла. awk используется для выбора md5sums (игнорируя имена файлов, которые могут быть не уникальными). Md5sums отсортированы. Затем возвращается md5sum этого отсортированного списка.

Я протестировал это, скопировав тестовый каталог:

rsync -a ~/pybin/ ~/pybin2/

Я переименовал некоторые файлы в ~/pybin2.

Команда find...md5sum возвращает тот же вывод для обоих каталогов.

2bcf49a4d19ef9abd284311108d626f1  -

Ответ 2

Создайте архив tar-архива на лету и трубу, чтобы md5sum:

tar c dir | md5sum

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

Ответ 3

Предложение

ire_and_curses использования tar c <dir> имеет некоторые проблемы:

  • tar обрабатывает записи каталога в том порядке, в котором они хранятся в файловой системе, и нет способа изменить этот порядок. Это может дать совершенно разные результаты, если у вас есть "тот же" каталог в разных местах, и я не знаю, как это исправить (tar не может "сортировать" свои входные файлы в определенном порядке).
  • Я обычно забочусь о том, совпадают ли номера groupid и ownerid, не обязательно ли то же самое, что и строковое представление группы/владельца. Это соответствует тому, что делает пример rsync -a --delete: он синхронизирует практически все (минус xattrs и acls), но будет синхронизировать владельца и группу на основе их идентификатора, а не строкового представления. Поэтому, если вы синхронизировались с другой системой, которая не обязательно имеет одинаковые пользователи/группы, вы должны добавить флаг --numeric-owner в tar
  • tar будет содержать имя файла каталога, который вы проверяете сам, что-то, о чем нужно знать.

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

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

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

Это решение, с которым я столкнулся:

dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum

Заметки об этом решении:

  • LC_ALL=C - обеспечить надежный порядок сортировки по всем системам.
  • Это не делает различия между каталогом "named\nwithanewline" и двумя каталогами "named" и "withanewline", но вероятность того, что это происходит, кажется очень маловероятной. Обычно это исправляется с флагом -print0 для find, но поскольку здесь есть другие вещи, я могу видеть только решения, которые сделают команду более сложной, чем это стоит.

PS: одна из моих систем использует ограниченный busybox find, который не поддерживает флаги -exec и -print0, а также добавляет '/' для обозначения каталогов, в то время как findutils find не кажется, поэтому для этой машины мне нужно запустить:

dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum

К счастью, у меня нет файлов/каталогов с символами новой строки в их именах, поэтому это не проблема в этой системе.

Ответ 4

Если вы заботитесь только о файлах, а не о пустых каталогах, это прекрасно работает:

find /path -type f | sort -u | xargs cat | md5sum

Ответ 5

Для полноты, md5deep (1); он не применяется непосредственно из-за требования к фильтру *.py, но должен отлично сочетаться с find (1).

Ответ 6

Решение, наиболее подходящее для меня:

find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum

Почему он работал лучше всего для меня:

  • обрабатывает имена файлов, содержащие пробелы
  • Игнорирует метаданные файловой системы
  • Обнаруживает, был ли файл переименован

Вопросы с другими ответами:

Метаданные файловой системы не игнорируются для:

tar c - "$path" | md5sum

Не обрабатывает имена файлов, содержащие пробелы, и не обнаруживает, был ли файл переименован:

find /path -type f | sort -u | xargs cat | md5sum

Ответ 7

Посмотрите этот и для более подробного объяснения.

Ответ 8

Если вы хотите, чтобы один md5sum охватывал весь каталог, я бы сделал что-то вроде

cat *.py | md5sum 

Ответ 9

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

grep -ar -e . /your/dir | md5sum | cut -c-32

То же, что и выше, но включает только файлы *.py

grep -ar -e . --include="*.py" /your/dir | md5sum | cut -c-32

Вы также можете следить за символическими ссылками, если хотите

grep -ar -e . /your/dir | md5sum | cut -c-32

Другие варианты, которые вы могли бы использовать с grep

-s, --no-messages         suppress error messages
-D, --devices=ACTION      how to handle devices, FIFOs and sockets;
-Z, --null                print 0 byte after FILE name
-U, --binary              do not strip CR characters at EOL (MSDOS/Windows)

Ответ 10

Найти GNU

find /path -type f -name "*.py" -exec md5sum "{}" +;

Ответ 11

Технически вам нужно запустить ls -lR *.py | md5sum. Если вы не беспокоитесь о том, что кто-то модифицирует файлы и дотронется до их первоначальных дат и никогда не меняет размеры файлов, вывод из ls должен указать вам, был ли файл изменен. Мой unix-foo слаб, поэтому вам может понадобиться еще несколько параметров командной строки, чтобы получить время создания и время изменения для печати. ls также сообщит вам, были ли изменены права на файлы (и я уверен, что есть переключатели, чтобы отключить это, если вам это не интересно).

Ответ 12

Я использую HashCopy для этого. Он может генерировать и проверять MD5 и SHA в одном файле или каталоге. Его можно загрузить с сайта www.jdxsoftware.org.

Ответ 13

Использование md5deep:

md5deep -r FOLDER | awk '{print $1}' | sort | md5sum

Ответ 14

У меня была такая же проблема, поэтому я придумал этот script, который просто перечисляет md5sums файлов в каталоге, и если он найдет подкаталог, он снова запускается оттуда, так как это произойдет, script иметь возможность запускать текущий каталог или из подкаталога, если указанный аргумент передается в $1

#!/bin/bash

if [ -z "$1" ] ; then

# loop in current dir
ls | while read line; do
  ecriv=`pwd`"/"$line
if [ -f $ecriv ] ; then
    md5sum "$ecriv"
elif [ -d $ecriv ] ; then
    sh myScript "$line" # call this script again
fi

done


else # if a directory is specified in argument $1

ls "$1" | while read line; do
  ecriv=`pwd`"/$1/"$line

if [ -f $ecriv ] ; then
    md5sum "$ecriv"

elif [ -d $ecriv ] ; then
    sh myScript "$line"
fi

done


fi

Ответ 15

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

cpio -i -e theDirname | md5sum

Ответ 16

Есть еще два решения:

Создать:

du -csxb /path | md5sum > file

ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum > /tmp/file

Check:

du -csxb /path | md5sum -c file

ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum -c /tmp/file