Bir yönetmenin MD5 toplamını bir toplam olarak nasıl alabilirim?


171

Md5sum programı, dizinler için sağlama toplamı sağlamaz. Alt dizinlerdeki dosyalar da dahil olmak üzere bir dizinin tüm içeriği için tek bir MD5 sağlama toplamı almak istiyorum. Yani, tüm dosyalardan yapılmış bir birleşik sağlama toplamı. Bunu yapmanın bir yolu var mı?

Yanıtlar:


186

Doğru yol, tam olarak neden sorduğunuza bağlıdır:

Seçenek 1: Yalnızca Verileri Karşılaştırın

Ağacın dosya içeriğinin sadece bir karmaşasına ihtiyacınız varsa, bu işe yarayacaktır:

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

Bu, ilk önce tüm dosya içeriğini ayrı ayrı, tahmin edilebilir bir sırayla özetler, ardından dosya adlarından ve MD5 karma listelerinden oluşan bir listeye geçer ve yalnızca ağaçtaki dosyalardan birinin içeriği değiştiğinde değişen tek bir değer verir.

Ne yazık ki, find -syalnızca macOS, FreeBSD, NetBSD ve OpenBSD'de kullanılan BSD find (1) ile çalışır. GNU veya SUS bulunan bir sistemde karşılaştırılabilir bir şey bulmak için (1), biraz daha çirkin bir şeye ihtiyacınız vardır:

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

Yerine find -sbir arama yaptık sort. -k 2Bit MD5 karma üzerinde atlamak için bunu söyler, bu yüzden sadece tarafından, sonu hat üzerinden alanda 2 içindedir dosya adları, sıralar sort'ın hesaplaşma.

Komutun bu sürümünde bir zayıflık var, bu durumda eğer içinde yeni satırlar olan herhangi bir dosya adınız varsa, aramaya birden çok satır gibi görüneceğinden kafanız karışabilir sort. find -sAğaç geçişi ve sıralama aynı programı dahilinde gerçekleşmesi nedeniyle varyant, bu sorunu yok find.

Her iki durumda da, hatalı pozitiflerden kaçınmak için sıralama gereklidir: en yaygın Unix / Linux dosya sistemleri, dizin listelerini kararlı ve öngörülebilir bir düzende tutmaz. Bunu ls, sizin için dizin içeriğini sessizce sıralayan böyle ve böyle bir işlem yapamazsınız. findolmadan -sveya bir sortçağrı, temel dosya sistemi onları geri döndürdüğü sırada herhangi bir sırayla dosyaları basacaktır; bu, girdi olarak verilen dosyaların sırası değişirse, bu komutun değiştirilmiş bir hash değeri vermesine neden olacaktır.

md5sumKomutları md5veya başka bir karma fonksiyonunu değiştirmeniz gerekebilir . Başka bir karma işlevi seçtiyseniz ve sisteminiz için komutun ikinci biçimine ihtiyacınız varsa, sortkomutu uygun şekilde ayarlamanız gerekebilir . Başka bir tuzak, bazı veri toplama programlarının bir dosya adı yazmadığı, eski Unix sumprogramının en önemli örneği olduğu .

Bu yöntem bir miktar verimsizdir, md5sumN + 1 defa çağırılır, burada N ağaçtaki dosya sayısıdır, ancak bu dosya ve dizin meta verilerini toplamak için gerekli bir maliyettir.

Seçenek 2: Verileri ve Meta Verileri Karşılaştırın

Ağaçtaki herhangi bir şeyin değiştiğini algılayabilmeniz gerekiyorsa , yalnızca dosya içeriğini değil tar, dizin içeriğini sizin için paketlemenizi isteyin ve ardından şunları gönderin md5sum:

$ tar -cf - somedir | md5sum

Çünkü taraynı zamanda vb dosya izinlerini, sahiplik, görür, bu da böyle şeyler değişiklikleri algılar, sadece içeriğini dosyaya değiştirir.

Bu yöntem, ağaçtan sadece bir kez geçmesini sağladığından ve karma programını yalnızca bir kez çalıştırdığından, oldukça hızlıdır.

Yukarıdaki findtemel yöntemde olduğu gibi, tartemel dosya sisteminin döndürdüğü sırada dosya adlarını işleyecektir. Başvurunuzda bunun olmasına neden olamayacağınızdan emin olabilirsiniz. Durumun muhtemel olduğu en az üç farklı kullanım modelini düşünebilirim. (Bunları listeleyeceğim, çünkü belirtilmemiş davranış bölgelerine giriyoruz. Her dosya sistemi, işletim sisteminin bir sürümünden diğerine bile farklı olabilir.)

Kendinizi yanlış pozitif bulursanız find | cpio, Gilles'un cevabındaki seçeneğe gitmenizi öneririm .


7
Karşılaştırma yapmak ve kullanmak find .yerine dizine gitmek en iyisidir find somedir. Bu yolla, dosya adları farklı yol özellikleri bulmak için kullanılırken aynıdır; Bu zor olabilir :-)
Abbafei

Dosyaları da mı sıralamalıyız?
CMCDragonkai

@ CMCDragonkai: Ne demek istiyorsun? İlk durumda, biz do dosya adlarının listesini sıralamak. İkinci durumda, kasıtlı olarak yapmayız, çünkü ilk cümlede vurgulanan herhangi bir şeyin bir dizindeki dosya sırasının değişmiş olması nedeniyle herhangi bir şeyi sıralamak istemezsiniz.
Warren Young,

@WarrenYoung Seçenek 2'nin neden her zaman daha iyi olmadığını neden biraz daha ayrıntılı olarak açıklayabilir misiniz? Daha hızlı, daha basit ve daha fazla çapraz platform gibi görünüyor. Hangi durumda seçenek 1 olmamalı?
Robin Winslow

Seçenek 1 alternatif: find somedir -type f -exec sh -c "openssl dgst -sha1 -binary {} | xxd -p" \; | sort | openssl dgst -sha1tüm dosya adlarını yoksaymak (yeni
hatlarla

38

Sağlama toplamı, dosyaların bir dize olarak deterministik ve açık bir şekilde gösterilmesi gerekir. Deterministic, aynı dosyaları aynı konumlara yerleştirirseniz aynı sonucu elde edeceğiniz anlamına gelir. Belirgin olmayan, iki farklı dosya grubunun farklı temsillere sahip olduğu anlamına gelir.

Veri ve meta veriler

Dosyaları içeren bir arşiv oluşturmak iyi bir başlangıçtır. Bu kesin olmayan bir temsildir (açıkçası, arşivi açarak dosyaları kurtaracağınız için). Tarihler ve sahiplik gibi dosya meta verileri içerebilir. Bununla birlikte, bu henüz doğru değil: bir arşiv belirsizdir, çünkü temsili dosyaların depolanma sırasına ve sıkıştırmaya uygulanabilirse bağlıdır.

Çözüm, dosya adlarını arşivlemeden önce sıralamaktır. Dosya adlarınız yeni satırlar içermiyorsa, find | sortonları listelemek için çalıştırabilir ve bu sırayla arşive ekleyebilirsiniz. Arşivleyiciye dizinlere tekrar girmemesini söyleyin. İşte POSIX pax, GNU tar ve cpio örnekleri :

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

Sadece isimler ve içerikler, düşük teknolojili yol

Dosya verilerini yalnızca meta verileri değil, hesaba katmak istiyorsanız, yalnızca dosya içeriğini içeren bir arşiv oluşturabilirsiniz, ancak bunun için standart araçlar yoktur. Dosya içeriğini eklemek yerine, dosyaların karma değerini dahil edebilirsiniz. Dosya adları yeni satır içermiyorsa ve yalnızca normal dosyalar ve dizinler varsa (sembolik bağlantılar veya özel dosyalar yok), bu oldukça kolaydır, ancak birkaç şeye dikkat etmeniz gerekir:

{ 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

Boş dizinler görünmez olacağından, sağlama listesine ek olarak bir dizin listesi de ekleriz. Dosya listesi (belirli, yeniden üretilebilir bir yerel ortamda - bana hatırlattığı için Peter.O sayesinde) sıralanır. echoiki parçayı ayırır (bu olmadan, adı md5sumsıradan dosyalar için de geçebilecek gibi görünen bazı boş dizinler oluşturabilirsiniz ). Ayrıca, uzatma saldırılarını önlemek için dosya boyutlarının bir listesini de içerir .

Bu arada, MD5 kullanımdan kaldırıldı. Varsa, SHA-2 veya en azından SHA-1'i kullanmayı düşünün.

İsimler ve veriler, isimlerdeki yeni hatları destekleyen

Dosya adlarını boş baytlarla ayırmak için GNU araçlarına dayanan yukarıdaki kodun bir çeşididir. Bu, dosya adlarının yeni satırlar içermesini sağlar. GNU özeti araçları çıktılarında özel karakterler alıntı yapar, bu yüzden belirsiz yeni satırlar olmayacaktır.

{ 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

Daha sağlam bir yaklaşım

İşte dosyalar hiyerarşisini tanımlayan bir karma oluşturan en düşük düzeyde test edilmiş Python betiği. Dizinleri ve dosya içeriğini hesaba katar ve sembolik bağları ve diğer dosyaları yok sayar ve herhangi bir dosya okunamıyorsa ölümcül bir hata verir.

#! /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()

Tamam, bu işe yarıyor. Ancak herhangi bir meta veri eklemeden bunu yapmanın bir yolu var mı? Şimdilik sadece gerçek içerikler için ona ihtiyacım var.

LC_ALL=C sortFarklı ortamlardan kontrol
etmeye

Bunun için bir Python programı yaptın mı? Teşekkürler! Bu gerçekten beklediğimden daha fazla. :-) Her neyse, bu yöntemleri ve Warren'ın yeni seçeneği 1'i kontrol edeceğim.

İyi cevap. LC_ALL=CBirden fazla makinede ve işletim sisteminde çalışıyorsanız , sıralama düzenini ayarlamak önemlidir.
Davor Cubranic

Ne cpio -o -demek istiyorsun? CPIO varsayılan olarak stdin / out kullanmıyor mu? GNU cpio 2,12 üretticpio: Too many arguments
Jan Tojnar

12

Md5deep'e bir göz atın . Md5deep'in ilginizi çekebilecek özelliklerinden bazıları:

Özyinelemeli işlem - md5deep özyinelemeyi bir dizin ağacının tamamını inceleyebilir. Diğer bir deyişle, MD5'i bir dizindeki her dosya için ve her alt dizindeki her dosya için hesaplayın.

Karşılaştırma modu - md5deep, bilinen karmaların bir listesini kabul edebilir ve bunları bir dizi girdi dosyasıyla karşılaştırabilir. Program, bilinen karma listesiyle eşleşen girdi dosyalarını veya eşleşmeyen dosyaları görüntüleyebilir.

...


Güzel, ama işe yaramadı, diyor .../foo: Is a directory, ne veriyor?
Camilo Martin

3
Kendi md5deep'i, OP'nin problemini, konsolide bir md5sum basmadığı için çözmez, sadece dizindeki her dosya için md5sum'ü yazdırır. Yani md5deep çıktısını md5sum edebilir, dedi - değil oldukça OP istediğini, ancak yakın! örneğin, geçerli dizin için: md5deep -r -l -j0 . | md5sum( -rözyinelemeli ise, -l"göreceli yolları kullan" anlamına gelir , böylece dosyaların mutlak yolu, iki dizinin içeriğini karşılaştırmaya çalışırken karışmaz ve -j0belirsizliği önlemek için 1 iş parçacığı kullanır. bireysel md5sums farklı sırayla iade ediliyor).
Stevie

Yoldaki bazı dosyalar / dizinler nasıl dikkate alınmaz?
Sandeepan Nath

9

Amacınız sadece iki dizin arasındaki farkları bulmaksa, diff kullanın.

Bunu dene:

diff -qr dir1 dir2

Evet, bu da faydalıdır. Sanırım bu komutta dir1 dir2 demek istedin.

1
Onlardan kaçınabileceğimde genellikle GUI kullanmıyorum, ancak dizin farklılığı için kdiff3 harika ve birçok platformda çalışıyor.
sinelaw

Bu komutla farklı dosyalar da bildirilir.
Serge Stroobandt

7

Her dosyayı yinelemeli olarak ve ardından elde edilen metni karma olarak alabilirsiniz:

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

Md5deep gereklidir.


1
ubuntu 16.04'te md5deepkullanmak yerine hashdeepmd5deep paketi sadece hashdeep için geçici bir kukladır.
palik

1
Hashdeep'i denedim. Yalnızca karma değerleri değil ## Invoked from: /home/myuser/dev/, geçerli yolunuz ve bunun da dahil olduğu bir başlık içerir ## $ hashdeep -s -r -l ~/folder/. Bu işlem sıralanmalı, geçerli klasörünüzü veya komut satırınızı değiştirirseniz son karma farklı olacaktır.
saat

3

Dosya adları hariç, yalnızca dosya içeriği

İçeriği farklı dizinlerde bulunduğundan sadece dosya isimlerini kontrol eden bir sürüme ihtiyacım vardı.

Bu sürüm (Warren Young'ın cevabı) çok yardımcı oldu, ancak benim md5sumsürümüm dosya adını (komutunu koyduğum yola göre) çıkarıyordu ve klasör isimleri farklıydı; 't.

Bunu düzeltmek için, benim durumumda, dosya ismini findçıktının her satırından çıkarmam gerekiyordu (sadece ilk kelimeyi boşluklarla ayrılmış olarak seçmelisiniz cut):

find -s somedir -type f -exec md5sum {} \; | cut -d" " -f1 | md5sum

Tekrarlanabilir bir liste elde etmek için sağlama toplamlarını da sıralamanız gerekebilir.
16'ya


3

nix-hashadlı Nix paket yöneticisi

Nix-hash komutu, her yolun içeriğinin şifreli karmasını hesaplar ve standart çıktıya yazdırır. Varsayılan olarak, bir MD5 karma değerini hesaplar, ancak diğer karma algoritmalar da kullanılabilir. Karma onaltılık olarak yazdırılır.

Karma, her yolun serileştirilmesi üzerinden hesaplanır: yola dayanan dosya sistemi ağacının dökümü. Bu, dizinlerin ve sembolik bağlantıların normal dosyaların yanı sıra karma olmasını da sağlar. Dökümü, nix-store --dump tarafından üretilen NAR biçimindedir. Böylece, nix-hash yolu, nix-store --dump yolu | md5sum.


2

Bu parçacığımı ılımlı birimler için kullanıyorum :

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

ve XXXL için bu :

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


-xdevBayrak ne yapar ?
czerasz

: Yazdığınız etmesi çağrısında man find) ve o güzel kitabını okumak
poige

İyi bir nokta :-). -xdev Don't descend directories on other filesystems.
czerasz

1
Bunun yeni, boş dosyaları göz ardı ettiğini unutmayın (bir dosyaya dokunuyormuş gibi).
RonJohn

Bunun tamamen farklı bir dosya ve dizin yapısı ile aynı md5sum vereceği birçok durum vardır. Dosyaların ve dizinlerin yeniden adlandırılması, dosyaların sıralama düzenini değiştirmezse, bunu hiçbir şekilde değiştirmez. Bu yüzden bu yaklaşımı tavsiye etmem.
Hans-Peter Störr

2

İyi bir ağaç kontrol toplamı Git'in ağaç kimliğidir.

Maalesef bunu yapabilen tek başına bir araç yok (en azından bilmiyorum), ancak Git kullanışlı iseniz, yeni bir havuz oluşturmuş gibi dizini kontrol etmek istediğiniz dosyaları ekleyebilirsiniz.

Bu, yalnızca içerik, dosya adları ve bazı azaltılmış dosya modlarını (çalıştırılabilir) içeren (yeniden üretilebilir) ağaç karmasını üretmenizi sağlar.


2

Bu mükemmel cevabın bir takipçisi olarak , kendinizi büyük bir dizin için sağlama toplamı hesaplamasını hızlandırmak istediğinizi düşünüyorsanız, GNU Parallel'ı deneyin :

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

(Bu bir Mac kullanıyor md5, gerektiğinde değiştirin.)

-kBayrak o talimat önemlidir parallelaksi genel toplamı dosyaları hepsi aynı olsa bile çalışacak şekilde çalıştırmak değişir olabilir düzeni korumak. -n 100her md5argümanı 100 argümanla çalıştırmayı söylüyor , bu en iyi çalışma süresi için ince ayar yapabileceğiniz bir parametredir. Ayrıca -Xbayrağına bakınız parallel(kişisel durumumda bir hataya neden olsa da.)


1

İyi bir şekilde test edilen ve yinelenenleri bulmak, hem veri hem de meta veriler üzerinde karşılaştırmalar yapmak, eklemelerin yanı sıra değişiklik ve kaldırmaları göstermek de dahil olmak üzere birçok işlemi destekleyen bir komut dosyası Parmak İzi'ni beğenebilir .

Şu anda parmak izi bir dizin için tek bir sağlama toplamı üretmiyor, ancak bu dizindeki tüm dosyalar için sağlama toplamı içeren bir transkript dosyası oluşturuyor.

fingerprint analyze

Bu index.fingerprint, sağlama toplamı, dosya adı ve dosya boyutlarını içeren geçerli dizinde üretilecektir . Varsayılan olarak hem kullanır MD5ve SHA1.256.

Gelecekte, Merkle Trees'e Parmak İzi'ne destek vermeyi umuyorum, bu da size tek bir üst düzey sağlama toplamı sağlayacaktır. Şu anda, doğrulama için bu dosyayı saklamanız gerekiyor.


1

Yeni çalıştırılabilir ya da zorlu çözümler istemedim, işte benim alıyorum:

#!/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

0

Sağlam ve temiz bir yaklaşım

  • İlk önce, mevcut hafızayı doldurma ! Dosyanın tamamını beslemek yerine, bir dosyayı parçalara ayırma
  • Farklı ihtiyaçlar / amaçlar için farklı yaklaşımlar (aşağıdakilerin tümü veya geçerli olanları seçin):
    • Dizin ağacındaki tüm girişlerin yalnızca giriş adını karma
    • Tüm girişlerin dosya içeriğini karma (meta gibi, inode numarası, ctime, atime, mtime, size, vb.
    • Sembolik bir bağlantı için, içeriği referans adıdır. Hash veya atlamayı seç
    • Girilen içeriğe sahip olurken sembolik bağlantıyı takip etmek (takip etmek) veya izlememek
    • Bu bir dizinse, içeriği sadece dizin girişleridir. Özyinelemeli hareket ederken, sonunda sonuçlanacak, ancak bu seviyenin dizin giriş adlarının bu dizini etiketlemek için kullanılması gerekir mi? Kullanımda, içeriği hızlı bir şekilde taramak zorunda kalmadan bir değişikliği hızlı bir şekilde tanımlamanın gerekli olduğu kullanım durumlarında faydalıdır. Bir örnek, bir dosyanın ismi değişir ancak içeriğin geri kalanı aynı kalır ve hepsi oldukça büyük dosyalardır.
    • Büyük dosyaları iyi kullanın (yine RAM'e dikkat edin)
    • Çok derin dizin ağaçları kullanın (açık dosya tanımlayıcılarına dikkat edin)
    • Standart olmayan dosya adlarını işleyin
    • Soket, borular / FIFO'lar, blok aygıtları, char aygıtları ile nasıl devam edilir? Onlara da sahip olmalı mı?
    • Geçiş yaparken herhangi bir girişin erişim zamanını güncellemeyin, çünkü bu bazı kullanım durumları için yan etki ve karşı üretken (sezgisel mi?) Olacaktır.

Bu benim başımda olan şey, pratik olarak bu konuda çalışarak biraz zaman geçiren herhangi biri, diğer alçı ve köşe davalarını yakalardı.

İşte bir araç (feragatname: Ben buna katkıda bulunuyorum) dtreetrawl , hafızaya çok ışık veren, çoğu vakayı ele alan, kenarlarda biraz kaba olabilir ancak oldukça yardımcı olmuştur.

Usage:
  dtreetrawl [OPTION...] "/trawl/me" [path2,...]

Help Options:
  -h, --help                Show help options

Application Options:
  -t, --terse               Produce a terse output; parsable.
  -d, --delim=:             Character or string delimiter/separator for terse output(default ':')
  -l, --max-level=N         Do not traverse tree beyond N level(s)
  --hash                    Hash the files to produce checksums(default is MD5).
  -c, --checksum=md5        Valid hashing algorithms: md5, sha1, sha256, sha512.
  -s, --hash-symlink        Include symbolic links' referent name while calculating the root checksum
  -R, --only-root-hash      Output only the root hash. Blank line if --hash is not set
  -N, --no-name-hash        Exclude path name while calculating the root checksum
  -F, --no-content-hash     Do not hash the contents of the file

Örnek insan dostu çıktı:

...
... //clipped
...
/home/lab/linux-4.14-rc8/CREDITS
        Base name                    : CREDITS
        Level                        : 1
        Type                         : regular file
        Referent name                :
        File size                    : 98443 bytes
        I-node number                : 290850
        No. directory entries        : 0
        Permission (octal)           : 0644
        Link count                   : 1
        Ownership                    : UID=0, GID=0
        Preferred I/O block size     : 4096 bytes
        Blocks allocated             : 200
        Last status change           : Tue, 21 Nov 17 21:28:18 +0530
        Last file access             : Thu, 28 Dec 17 00:53:27 +0530
        Last file modification       : Tue, 21 Nov 17 21:28:18 +0530
        Hash                         : 9f0312d130016d103aa5fc9d16a2437e

Stats for /home/lab/linux-4.14-rc8:
        Elapsed time     : 1.305767 s
        Start time       : Sun, 07 Jan 18 03:42:39 +0530
        Root hash        : 434e93111ad6f9335bb4954bc8f4eca4
        Hash type        : md5
        Depth            : 8
        Total,
                size           : 66850916 bytes
                entries        : 12484
                directories    : 763
                regular files  : 11715
                symlinks       : 6
                block devices  : 0
                char devices   : 0
                sockets        : 0
                FIFOs/pipes    : 0

Genel tavsiye her zaman bekler, ancak en iyi cevaplar özeldir ve uygun durumlarda kodla birlikte verilir. Başvurduğunuz aracı kullanma konusunda deneyiminiz varsa, lütfen ekleyin.
bu5hman

@ bu5hman Tabii! Gelişimine katıldığımdan beri ne kadar iyi çalıştığı hakkında daha fazla şey söylemekten (eldivenlik etmek) pek rahat değildim.
altıda

0

Her dizindeki tüm dosyalar için ayrı ayrı yapmak.

# 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

POSIX arşiv formatına geçiş, GNU Tar tabanlı sağlama toplamını etkiler

Bu cevabın, bir süre önce Warren Young ve Gilles'un mükemmel cevaplarında (diğer şeylerin yanı sıra) önerildiği gibi, dizinlerin içeriğini elde etmek için Tar çıktısını kullanma yaklaşımında ek bir güncelleme olması amaçlanmıştır .

O zamandan beri, en azından openSUSE (12.2 sürümünden beri) varsayılan GNU Tar biçimini "GNU tar 1.13.x biçiminden" (hafif) üstün "POSIX 1003.1-2001 (pax) biçimine" değiştirdi . Ayrıca yukarı (GNU Tar geliştiriciler arasında) onlar, örneğin son paragrafa bakın, aynı taşıma işlemini gerçekleştirmek için tartışmak bu sayfayı ait GNU Tar kılavuzuna :

GNU tar için varsayılan format derleme zamanında tanımlanmıştır. tar --helpÇalıştırarak ve çıktısının son satırlarını inceleyerek kontrol edebilirsiniz . Genellikle, GNU tar gnuformatta arşiv oluşturmak için yapılandırılmıştır , ancak gelecekteki sürüm değişecektir posix.

(Bu sayfa ayrıca GNU Tar'da mevcut olan farklı arşiv formatları hakkında da güzel bir derleme sunar.)

Dizin içeriğini tarh ettiğimiz ve sonucu elde ettiğimiz ve özel önlemler almadan, GNU'dan POSIX formatına yapılan bir değişikliğin şu sonuçları vardır:

  • Aynı dizin içeriğine rağmen, ortaya çıkan sağlama toplamı farklı olacaktır.

  • Aynı dizin içeriğine rağmen, varsayılan pax başlıkları kullanılırsa ortaya çıkan sağlama toplamı çalıştırmadan farklı olacaktır.

Sonuncusu, POSIX (pax) formatının, %d/PaxHeaders.%p/%fGNU Tar'da varsayılan olan bir format dizesi tarafından belirlenen genişletilmiş pax başlıklarını içermesinden kaynaklanmaktadır . Bu dizgede, belirleyici %p, elbette run-rundan farklı olan üretici Tar işleminin işlem kimliği ile değiştirilir. Ayrıntılar için GNU Tar el kitabının bu bölümüne ve özellikle buna bakın.

Şimdi, 2019-03-28 arasında çıkan, bu konuyu etkisiz hale getiren bir taahhüt var .

Dolayısıyla, GNU Tar'ı verilen kullanım durumunda kullanmaya devam edebilmek için aşağıdaki alternatif seçenekleri önerebilirim:

  • --format=gnuArşive açıkça "eski" biçiminde bir arşiv oluşturmasını bildirmek için Tar seçeneğini kullanın . Bu "eski" sağlama toplamlarını doğrulamak için zorunludur.

  • Daha yeni POSIX biçimini kullanın, ancak açıkça örneğin uygun bir pax başlığı belirtin --pax-option="exthdr.name=%d/PaxHeaders/%f". Ancak, bu "eski" sağlama toplamları ile geriye dönük uyumluluğu bozar.

Meta verileri içeren dizin içeriğinin sağlama toplamlarını hesaplamak için düzenli olarak kullandığım bir Bash kodu parçası:

( export LC_ALL=C
  find <paths> ! -type s -print0 |
  sort -z |
  tar cp --format=gnu --numeric-owner \
         --atime-preserve \
         --no-recursion --null --files-from - |
  md5sum --binary; )

Burada, <paths>sağlama toplamı tarafından kapsanmasını istediğim tüm dizinlerin yollarının boşlukla ayrılmış bir listesi ile değiştirilir. C yerel ayarını kullanmak, dosya adlarının boş bayt ayırımını yapmak ve arşivdeki dosyaların dosya düzeninden bağımsız bir sırasını bulmak için bul ve sıralamanın kullanılması zaten diğer cevaplarda yeterince tartışılmıştır.

Çevreleyen parantezler LC_ALLayarı alt kabukta lokal tutar .

Buna ek olarak, ben ifadesini kullanmak ! -type sile findsoket dosyaları dizin içinde bulunmayabilir oluşabilir Tar uyarıları önlemek için: GNU Tar arşivi yuvalarını yapar değil. Atlanan yuvalar hakkında bilgilendirilmeyi tercih ediyorsanız, bu ifadeyi uzak bırakın.

--numeric-ownerTar ile kullanıyorum , daha sonra da tüm dosya sahiplerinin bilinmediği sistemlerde bile sağlama toplamlarını doğrulayabilmek için kullanıyorum.

--atime-preserveTar seçenek daha iyi eğer atlanırsa herhangi <paths>bir salt okunur monte cihazda yalanlar. Aksi takdirde, erişim zaman damgası Tar'ı geri yükleyemeyen her dosya için uyarılırsınız. Yazma etkin olduğunda <paths>, bu seçeneği, karma dizinlerdeki erişim zaman damgalarını korumak için de kullanırım.

--no-recursionZaten Gilles teklifinde kullanılmış olan Tar seçeneği , Tar'ın tekrarlı olarak dizinlere indirilmesini engeller ve bunun yerine sıralanan findçıktıdan beslendiği herhangi bir şey hakkında dosya halinde dosya çalıştırmasını engeller .

Ve son olarak, kullandığım doğru değil md5sum: Aslında kullanıyorum sha256sum.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.