Jak obliczyć sumę kontrolną md5 katalogu?

Muszę obliczyć sumaryczną sumę kontrolną md5 dla wszystkich plików określonego typu (na przykład*.py) umieszczonych w katalogu i wszystkich podkatalogach.

Jaki jest najlepszy sposób, aby to zrobić?

Edit: proponowane rozwiązania są bardzo ładne, ale to nie jest dokładnie to, czego potrzebuję. Szukam rozwiązania, aby uzyskać sumę kontrolną, która jednoznacznie identyfikuje katalog jako całość - w tym zawartość wszystkich jego podkatalogów.

Author: zx8754, 2009-11-01

15 answers

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

Polecenie find wyświetla listę wszystkich plików, które kończą się w .py. Suma MD5 jest obliczana dla każdego pliku .py. awk służy do usuwania sum MD5 (ignorując nazwy plików, które mogą nie być unikalne). Md5sums są sortowane. Następnie zwracana jest suma MD5 tej posortowanej listy.

Przetestowałem to kopiując katalog testowy:

rsync -a ~/pybin/ ~/pybin2/

Zmieniłem nazwę niektórych plików w ~ / pybin2.

Polecenie find...md5sum zwraca to samo wyjście dla obu katalogów.

2bcf49a4d19ef9abd284311108d626f1  -
 141
Author: unutbu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-11 12:40:57

Utwórz plik archiwum tar w locie i prześlij go do md5sum:

tar c dir | md5sum

To tworzy pojedynczą sumę MD5, która powinna być unikalna dla konfiguracji plików i podkatalogów. Na dysku nie są tworzone żadne pliki.

 158
Author: ire_and_curses,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-01 15:47:01

Sugestia ire_and_curses użycia tar c <dir> ma pewne problemy:

  • tar przetwarza wpisy w katalogu w kolejności, w jakiej są przechowywane w systemie plików i nie ma możliwości zmiany tej kolejności. To skutecznie moĹźe daÄ ‡ zupeĹ ' nie róşne wyniki, jeĹ "li masz" ten sam "katalog w róşnych miejscach i nie wiem jak to naprawiÄ ‡ (tar nie moĹźe" sortowaÄ ‡ "swoich plikĂłw wejĹ" ciowych w okreĹ "lonej kolejnoĹ" ci).
  • zwykle zależy mi na tym, czy liczby groupid i ownerid są takie same, niekoniecznie, czy reprezentacja łańcuchowa grupy / właściciela jest taka sama. Jest to zgodne z tym, co robi na przykład rsync -a --delete: synchronizuje praktycznie wszystko (minus xattrs i acls), ale synchronizuje właściciela i grupę na podstawie ich ID, a nie na reprezentacji łańcuchów. Jeśli więc zsynchronizowałeś się z innym systemem, który niekoniecznie ma tych samych użytkowników/grupy, powinieneś dodać flagę --numeric-owner do tar
  • tar będzie zawierał nazwę pliku katalogu, który sam sprawdzasz, tylko coś, o czym warto wiedzieć.

Dopóki nie ma poprawki dla pierwszego problemu (lub jeśli nie jesteś pewien, że nie wpływa na ciebie), nie używałbym tego podejścia.

Zaproponowane powyżej rozwiązania bazujące na find również nie są dobre, ponieważ zawierają tylko pliki, a nie katalogi, co staje się problemem, jeśli sumowanie kontrolne powinno pamiętać o pustych katalogach.

Wreszcie, większość sugerowanych rozwiązań nie sortuje konsekwentnie, ponieważ zestawienie może być inne w różnych systemach.

Oto rozwiązanie, które wymyśliłem:

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

Uwagi na temat tego rozwiązania:

  • LC_ALL=C jest zapewnienie niezawodnego porządku sortowania w systemach
  • to nie odróżnia katalogu" named\nwithanewline "od dwóch katalogów "named" i "withanewline" , ale szansa na to wydaje się bardzo mało prawdopodobna. Zazwyczaj naprawia się to flagą -print0 dla find, ale ponieważ dzieje się tu coś innego, widzę tylko rozwiązania to by bardziej skomplikowało dowodzenie.

PS: Jeden z moich systemów używa ograniczonego busybox find, który nie obsługuje znaczników -exec ani -print0, a także dodaje ' / ' do oznaczania katalogów, podczas gdy findutils find nie wydaje się, więc dla tej maszyny muszę uruchomić:

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

Na szczęście nie mam plików/katalogów z nowymi liniami w nazwach, więc nie jest to problem w tym systemie.

 42
Author: Dieter_be,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-20 15:53:09

Jeśli zależy Ci tylko na plikach, a nie pustych katalogach, działa to ładnie:

find /path -type f | sort -u | xargs cat | md5sum
 13
Author: Simon Guest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-09 21:33:31

Dla kompletności istnieje md5deep (1) ; nie jest bezpośrednio stosowane ze względu na Wymaganie filtra*. py, ale powinno działać dobrze razem z find(1).

 10
Author: Michael Shigorin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-04 21:58:16

Rozwiązanie, które działało najlepiej dla mnie:

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

Powód, dla którego to działało najlepiej dla mnie:

  1. obsługuje nazwy plików zawierające spacje
  2. ignoruje meta-dane systemu plików
  3. wykrywa, czy plik został przemianowany

Problemy z innymi odpowiedziami:

Metadane systemu plików nie są ignorowane dla:

tar c - "$path" | md5sum

Nie obsługuje nazw plików zawierających spacje ani nie wykrywa, czy nazwa pliku została zmieniona:

find /path -type f | sort -u | xargs cat | md5sum
 8
Author: Tiago Lopo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-08 10:28:55

Jeśli chcesz jedno md5sum obejmujące cały katalog, zrobiłbym coś takiego

cat *.py | md5sum 
 3
Author: Ramon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-01 14:39:16

Suma kontrolna wszystkich plików, w tym zarówno zawartości, jak i ich nazw plików

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

To samo co wyżej, ale tylko z plikami*. py

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

Możesz również śledzić dowiązania symboliczne, jeśli chcesz

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

Inne opcje, które możesz rozważyć używając 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)
 3
Author: moander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-02 14:35:41

GNU find

find /path -type f -name "*.py" -exec md5sum "{}" +;
 2
Author: ghostdog74,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-01 14:50:58

Technicznie wystarczy uruchomić ls -lR *.py | md5sum. Jeśli nie martwisz się, że ktoś zmodyfikuje pliki i przywróci ich oryginalne daty i nigdy nie zmieni rozmiaru plików, wyjście z ls powinno ci powiedzieć, czy Plik się zmienił. Mój unix-foo jest słaby, więc możesz potrzebować więcej parametrów wiersza poleceń, aby uzyskać czas tworzenia i modyfikacji do wydruku. ls powie Ci również, czy uprawnienia do plików się zmieniły (i jestem pewien, że są przełączniki, które wyłączają, jeśli nie obchodzi cię to).

 2
Author: jmucchiello,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-01 22:43:13

Używam do tego HashCopy. Może wygenerować i zweryfikować MD5 i SHA na jednym pliku lub katalogu. Można go pobrać z www.jdxsoftware.org.

 2
Author: William Leng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-20 19:59:12

Using md5deep:

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

 2
Author: doesntreallymatter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-17 21:49:49

Miałem ten sam problem, więc wpadłem na ten skrypt, który po prostu wyświetla sumy MD5 plików w katalogu i jeśli znajdzie podkatalog, uruchomi się ponownie stamtąd, aby to się stało, skrypt musi być w stanie uruchomić przez bieżący katalog lub z podkatalogu, jeśli wspomniany argument jest przekazywany w $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
 1
Author: alan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-16 21:39:43

Jeśli chcesz być naprawdę niezależny od atrybutów systemu plików i od różnic na poziomie bitów niektórych wersji tar, możesz użyć cpio:

cpio -i -e theDirname | md5sum
 1
Author: peterh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-25 13:49:11

Istnieją jeszcze dwa rozwiązania:

Create:

du -csxb /path | md5sum > file

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

Sprawdzić:

du -csxb /path | md5sum -c file

ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum -c /tmp/file
 0
Author: Nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-29 14:34:48