GNU/Linux >> Znalost Linux >  >> Linux

Jak mohu vypočítat kontrolní součet md5 adresáře?

Vytvořte archivní soubor tar za běhu a převeďte jej do md5sum :

tar c dir | md5sum

To vytvoří jedinou hodnotu hash MD5, která by měla být jedinečná pro nastavení vašeho souboru a podadresáře. Na disku se nevytvářejí žádné soubory.


Pokud se staráte pouze o soubory a ne o prázdné adresáře, funguje to dobře:

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

ire_and_curses návrh na použití tar c <dir> má nějaké problémy:

  • tar zpracovává položky adresáře v pořadí, v jakém jsou uloženy v souborovém systému, a neexistuje způsob, jak toto pořadí změnit. To může efektivně přinést zcela odlišné výsledky, pokud máte "stejný" adresář na různých místech, a nevím, jak to opravit (tar nemůže "seřadit" své vstupní soubory v určitém pořadí).
  • Obvykle mi záleží na tom, zda jsou čísla groupid a ownerid stejná, ne nezbytně na tom, zda je řetězec reprezentace skupiny/vlastníka stejný. To je v souladu s tím, co například rsync -a --delete dělá:synchronizuje prakticky vše (minus xattrs a acls), ale bude synchronizovat vlastníka a skupinu na základě jejich ID, nikoli podle reprezentace řetězců. Pokud jste tedy provedli synchronizaci do jiného systému, který nemusí mít nutně stejné uživatele/skupiny, měli byste přidat --numeric-owner flag to tar
  • tar bude obsahovat název souboru adresáře, který kontrolujete, což je třeba si uvědomit.

Dokud neexistuje žádná oprava pro první problém (nebo pokud si nejste jisti, že se vás to netýká), nepoužil bych tento přístup.

Navrhovaný find Řešení založená na - také nejsou dobrá, protože zahrnují pouze soubory, nikoli adresáře, což se stává problémem, pokud byste měli mít kontrolní součet na paměti prázdné adresáře.

A konečně, většina navrhovaných řešení se neřadí konzistentně, protože řazení se může mezi systémy lišit.

Toto je řešení, se kterým jsem přišel:

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

Poznámky k tomuto řešení:

  • LC_ALL=C je zajistit spolehlivé řazení napříč systémy
  • To nerozlišuje mezi adresářem "pojmenovaný\nwithanewline" a dvěma adresáři "named" a "withanewline", ale pravděpodobnost, že k tomu dojde, se zdá být velmi nepravděpodobná. Obvykle se to řeší pomocí -print0 příznak pro find , ale protože se zde dějí další věci, vidím pouze řešení, která by příkaz zkomplikovala, než stojí za to.

PS:jeden z mých systémů používá omezený busybox find který nepodporuje -exec ani -print0 flags a také připojuje '/' k označení adresářů, zatímco findutils find se nezdá, takže pro tento počítač musím spustit:

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štěstí nemám žádné soubory/adresáře s novými řádky v názvech, takže v tomto systému to není problém.


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

Najít příkaz vypíše všechny soubory, které končí na .py.Hodnota hash MD5 se vypočítá pro každý soubor .py. AWK se používá k vybírání hodnot hash MD5 (ignoruje se názvy souborů, které nemusí být jedinečné). Hodnoty hash MD5 jsou seřazeny. Poté je vrácena hodnota hash MD5 tohoto seřazeného seznamu.

Testoval jsem to zkopírováním testovacího adresáře:

rsync -a ~/pybin/ ~/pybin2/

Přejmenoval jsem některé soubory v ~/pybin2 .

find...md5sum příkaz vrátí stejný výstup pro oba adresáře.

2bcf49a4d19ef9abd284311108d626f1  -

Chcete-li vzít v úvahu rozložení souboru (cesty), takže se kontrolní součet změní, pokud je soubor přejmenován nebo přesunut, lze příkaz zjednodušit:

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

V systému macOS s md5 :

find /path/to/dir/ -type f -name "*.py" -exec md5 {} + | md5

Linux
  1. Jak vyloučit adresář v find . příkaz

  2. Jak mohu zkontrolovat, zda adresář existuje?

  3. Jak spočítat počet souborů v každém adresáři?

  1. Jak mohu najít soubor/adresář, který by mohl být kdekoli na příkazovém řádku linuxu?

  2. Jak mohu vyloučit adresář z příkazu ls

  3. Jak najdu dostupná síťová rozhraní?

  1. Shell - Jak najít adresář nějakého příkazu?

  2. Jak najít částečnou cestu k adresáři?

  3. Nemůžete najít .so ve stejném adresáři jako spustitelný soubor?