How can I calculate an MD5 checksum of a directory?
I need to calculate a summary MD5 checksum for all files of a particular type ( *.py for example) placed under a directory and all sub-directories. What is the best way to do that? The proposed solutions are very nice, but this is not exactly what I need. I’m looking for a solution to get a single summary checksum which will uniquely identify the directory as a whole — including content of all its subdirectories.
Why would you have two directory trees that may or may not be «the same» that you want to uniquely identify? Does file create/modify/access time matter? Is version control what you really need?
What is really matter in my case is similarity of the whole directory tree content which means AFAIK the following: 1) content of any file under the directory tree has not been changed 2) no new file was added to the directory tree 3) no file was deleted
16 Answers 16
Create a tar archive file on the fly and pipe that to md5sum :
This produces a single MD5 hash value that should be unique to your file and sub-directory setup. No files are created on disk.
@CharlesB with a single check-sum you never know which file is different. The question was about a single check-sum for a directory.
ls -alR dir | md5sum . This is even better no compression just a read. It is unique because the content contains the mod time and size of file 😉
@Daps0l — there is no compression in my command. You need to add z for gzip, or j for bzip2. I’ve done neither.
Take care that doing this would integrate the timestamp of the files and other stuff in the checksum computation, not only the content of the files
This is cute, but it doesn’t really work. There’s no guarantee that tar ing the same set of files twice, or on two different computers, will yield the same exact result.
find /path/to/dir/ -type f -name "*.py" -exec md5sum <> + | awk '' | sort | md5sum
The find command lists all the files that end in .py. The MD5 hash value is computed for each .py file. AWK is used to pick off the MD5 hash values (ignoring the filenames, which may not be unique). The MD5 hash values are sorted. The MD5 hash value of this sorted list is then returned.
I’ve tested this by copying a test directory:
I renamed some of the files in ~/pybin2.
The find. md5sum command returns the same output for both directories.
2bcf49a4d19ef9abd284311108d626f1 -
To take into account the file layout (paths), so the checksum changes if a file is renamed or moved, the command can be simplified:
find /path/to/dir/ -type f -name "*.py" -exec md5sum <> + | md5sum
find /path/to/dir/ -type f -name "*.py" -exec md5 <> + | md5
Note that the same checksum will be generated if a file gets renamed. So this doesn’t truly fit a «checksum which will uniquely identify the directory as a whole» if you consider file layout part of the signature.
you could slightly change the command-line to prefix each file checksum with the name of the file (or even better, the relative path of the file from /path/to/dir/) so it is taken into account in the final checksum.
@zim2001: Yes, it could be altered, but as I understood the problem (especially due to the OP’s comment under the question), the OP wanted any two directories to be considered equal if the contents of the files were identical regardless of filename or even relative path.
- tar processes directory entries in the order which they are stored in the filesystem, and there is no way to change this order. This effectively can yield completely different results if you have the «same» directory on different places, and I know no way to fix this (tar cannot «sort» its input files in a particular order).
- I usually care about whether groupid and ownerid numbers are the same, not necessarily whether the string representation of group/owner are the same. This is in line with what for example rsync -a —delete does: it synchronizes virtually everything (minus xattrs and acls), but it will sync owner and group based on their ID, not on string representation. So if you synced to a different system that doesn’t necessarily have the same users/groups, you should add the —numeric-owner flag to tar
- tar will include the filename of the directory you’re checking itself, just something to be aware of.
As long as there is no fix for the first problem (or unless you’re sure it does not affect you), I would not use this approach.
The proposed find -based solutions are also no good because they only include files, not directories, which becomes an issue if you the checksumming should keep in mind empty directories.
Finally, most suggested solutions don’t sort consistently, because the collation might be different across systems.
This is the solution I came up with:
dir=; (find "$dir" -type f -exec md5sum <> +; find "$dir" -type d) | LC_ALL=C sort | md5sum
Notes about this solution:
- The LC_ALL=C is to ensure reliable sorting order across systems
- This doesn’t differentiate between a directory «named\nwithanewline» and two directories «named» and «withanewline», but the chance of that occurring seems very unlikely. One usually fixes this with a -print0 flag for find , but since there’s other stuff going on here, I can only see solutions that would make the command more complicated than it’s worth.
PS: one of my systems uses a limited busybox find which does not support -exec nor -print0 flags, and also it appends ‘/’ to denote directories, while findutils find doesn’t seem to, so for this machine I need to run:
dir=; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum
Luckily, I have no files/directories with newlines in their names, so this is not an issue on that system.
контрольная сумма для всей папки в терминале linux?
требуется сверить контрольную сумму залитых на сервер кучи файлов, которые находятся в одной папке. по сути без разницы каким алгоритмом, лишь бы сверить, чем менее ресурснозатратно и более быстро, тем лучше. можно выполнить чек сумм прямо на папку? как? например папка тут /home/user/thisfolderforchksumm вбил :~/thisfolderforchksumm$ md5sum — может конечно и работает, но что-то долго не выводит, а я для примера всего лишь два файла туда сунул (из 1000 нужных). ну или контрольную сумму на всю сразу группу файлов, находящиеся в этой папке одной командой? как вариант — в filezilla нет функции сравнения именно по хешу? (просто сравнение каталогов знаю) сенкс
md5sum без параметров ожидает данных со стандартного ввода. он никогда не сакончиться пока Ctrl+D не нажмете. сделайте md5sum *
ок, спасибо, но md5sum * выкатывает суммы всех файлов, находящихся в папке, по каждому отдельно, если зайти в нее ‘:~/thisfolderforchksumm$ md5sum *’ а как на всю папку? я как не прописывал, только ругается что директория.. как прописать на папку?
находясь в папке cat * | md5sum правда ему важен порядок файлов, а в каком порядке шел разложит * я не в курсе.
ок, спасибо! но ведь, если мне нужна полная копия всех внутри файлов и они все лежать подряд, то по идее ведь не должна контрольная сумма отличаться (какая разница как он их там высчитывает?) . ?
1 ответ 1
прочитать (fopen()+fread() и т.д. и т.п.) можно содержимое файла, но что именно должно происходить при «чтении самого каталога» (1), насколько мне известно, не описано ни в каком стандарте (ну, разве что в plan9 что-нибудь эдакое выдумали по поводу «чтения каталога»).
если вы принципиально не пользуетесь чем-либо вроде программы rsync для копирования и/или сверки актуальности копии файлов/каталогов, то, чтобы не сравнивать два списка с контрольными суммами (что, к слову, очень легко сделать с помощью программы diff), можно подсчитать контрольные суммы самих списков:
вместо программы sum можно использовать любую другую аналогичную программу: cksum, md*sum, sha*sum и т.п.
промежуточный вызов программы sort для сортировки списка контрольных сумм — на всякий случай. ведь теоретически оболочка может выдать список одних и тех же файлов («раскрывая» мета-символ * ) в разных случаях в разном порядке.
если в каталоге имеются вложенные каталоги с файлами, и требуется получить и их контрольные суммы, то можно воспользоваться связкой программ find+xargs:
$ find -type f | xargs sum | sort | sum
Проверка контрольной суммы Linux
Контрольная сумма — это цифра или строка, которая вычисляется путем суммирования всех цифр нужных данных. Ее можно использовать в дальнейшем для обнаружения ошибок в проверяемых данных при хранении или передаче. Тогда контрольная сумма пересчитывается еще раз и полученное значение сверяется с предыдущим.
В этой небольшой статье мы рассмотрим что такое контрольная сумма Linux, а также как выполнять проверку целостности файлов с помощью контрольных сумм md5.
Что такое MD5?
Контрольные суммы Linux с вычисляемые по алгоритму MD5 (Message Digest 5) могут быть использованы для проверки целостности строк или файлов. MD5 сумма — это 128 битная строка, которая состоит из букв и цифр. Суть алгоритма MD5 в том, что для конкретного файла или строки будет генерироваться 128 битный хэш, и он будет одинаковым на всех машинах, если файлы идентичны. Трудно найти два разных файла, которые бы выдали одинаковые хэши.
В Linux для подсчета контрольных сумм по алгоритму md5 используется утилита md5sum. Вы можете применять ее для проверки целостности загруженных из интернета iso образов или других файлов.
Эта утилита позволяет не только подсчитывать контрольные суммы linux, но и проверять соответствие. Она поставляется в качестве стандартной утилиты из набора GNU, поэтому вам не нужно ничего устанавливать.
Проверка контрольных сумм в Linux
Синтаксис команды md5sum очень прост:
$ md5sum опции файл
Опций всего несколько и, учитывая задачи утилиты, их вполне хватает:
- -c — выполнить проверку по файлу контрольных сумм;
- -b — работать в двоичном формате;
- -t — работать в текстовом формате;
- -w — выводить предупреждения о неверно отформатированном файле сумм;
- —quiet — не выводить сообщения об успешных проверках.
Сначала скопируйте файл /etc/group в домашнюю папку чтобы на нем немного поэкспериментировать:
Например, давайте подсчитаем контрольную сумму для файла /etc/group:
Или вы можете сохранить сразу эту сумму в файл для последующей проверки:
Затем каким-либо образом измените этот файл, например, удалите первую строчку и снова подсчитайте контрольные суммы:
Как видите, теперь значение отличается, а это значит, что содержимое файла тоже изменилось. Дальше верните обратно первую строчку root:x:0: и скопируйте этот файл в groups_list и
Затем опять должна быть выполнена проверка контрольной суммы linux:
Сумма соответствует первому варианту, даже несмотря на то, что файл был переименован. Обратите внимание, что md5sum работает только с содержимым файлов, ее не интересует ни его имя, ни его атрибуты. Вы можете убедиться, что оба файла имеют одинаковые суммы:
md5sum groups groups_list
Вы можете перенаправить вывод этой команды в файл, чтобы потом иметь возможность проверить контрольные суммы:
md5sum groups groups_list > groups.md5
Чтобы проверить, не были ли файлы изменены с момента создания контрольной суммы используйте опцию -c или —check. Если все хорошо, то около каждого имени файла появится слово OK или ЦЕЛ:
Но теперь вы не можете переименовывать файлы, потому что при проверке утилита будет пытаться открыть их по имени и, естественно, вы получите ошибку. Точно так же все работает для строк:
echo -n «Losst» | md5sum —
$ echo -n «Losst Q&A» | md5sum —
Выводы
Из этой статьи вы узнали как выполняется получение и проверка контрольной суммы linux для файлов и строк. Хотя в алгоритме MD5 были обнаружены уязвимости, он все еще остается полезным, особенно если вы доверяете инструменту, который будет создавать хэши.
Проверка целостности файлов Linux — это очень важный аспект использования системы. Контрольная сумма файла Linux используется не только вручную при проверке загруженных файлов, но и во множестве системных программ, например, в менеджере пакетов. Если у вас остались вопросы, спрашивайте в комментариях!
На завершение небольшое видео по теме:
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.