मुझे एक निर्देशिका की MD5 राशि एक राशि के रूप में कैसे मिलती है?


171

Md5sum प्रोग्राम निर्देशिकाओं के लिए चेकसम प्रदान नहीं करता है। मैं निर्देशिका की संपूर्ण सामग्री के लिए उप-निर्देशिकाओं में फ़ाइलों सहित एकल एमडी 5 चेकसम प्राप्त करना चाहता हूं। यही है, सभी फ़ाइलों में से एक संयुक्त चेकसम बनाया गया है। क्या इसे करने का कोई तरीका है?

जवाबों:


186

सही तरीका इस बात पर निर्भर करता है कि आप क्यों पूछ रहे हैं:

विकल्प 1: केवल डेटा की तुलना करें

यदि आपको पेड़ की फ़ाइल सामग्री के लिए एक हैश चाहिए, तो यह चाल चलेगा:

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

यह पहली बार व्यक्तिगत रूप से एक पूर्वानुमेय क्रम में सभी फ़ाइल सामग्रियों को संक्षेप में प्रस्तुत करता है, फिर फ़ाइल नामों और एमडी 5 हैश की सूची को स्वयं हीहेड करने के लिए पास करता है, एक एकल मान देता है जो केवल तब बदलता है जब पेड़ में फ़ाइलों में से एक की सामग्री बदल जाती है।

दुर्भाग्य से, find -sकेवल BSD खोजने (1) के साथ काम करता है, जिसका उपयोग macOS, FreeBSD, NetBSD और OpenBSD में किया जाता है। जीएनयू या एसयूएस (1) के साथ एक प्रणाली पर तुलनीय कुछ प्राप्त करने के लिए, आपको कुछ बदसूरत होने की आवश्यकता है:

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

हमने find -sएक कॉल से बदल दिया है sort-k 2बिट यह बताता है MD5 हैश के ऊपर छोड़, तो यह केवल फ़ाइल नाम है, जो, अंत लाइन के माध्यम से क्षेत्र 2 में हैं द्वारा सॉर्ट करता sortहै गणना।

कमांड के इस संस्करण के साथ एक कमजोरी है, जो यह है कि यह भ्रमित होने के लिए उत्तरदायी है यदि आपके पास उन में नईलाइनों के साथ कोई फ़ाइल नाम है, क्योंकि यह sortकॉल करने के लिए कई लाइनों की तरह दिखेगा । find -sसंस्करण है, कि समस्या नहीं है, क्योंकि पेड़ ट्रावर्सल और छंटाई एक ही कार्यक्रम के भीतर हो find

या तो मामले में, झूठी सकारात्मक से बचने के लिए छंटाई आवश्यक है: सबसे आम यूनिक्स / लिनक्स फाइल सिस्टम एक स्थिर, अनुमानित क्रम में निर्देशिका लिस्टिंग को बनाए नहीं रखते हैं। आपको इसका उपयोग करने lsऔर इस तरह का एहसास नहीं हो सकता है , जो चुपचाप आपके लिए निर्देशिका सामग्री को सॉर्ट करता है। findबिना -sया sortकॉल के फाइल को प्रिंट करने के लिए जा रहा है जो कुछ भी क्रम में अंतर्निहित फाइलसिस्टम उन्हें वापस कर देता है, जो इस आदेश का कारण बदल दिया गया हैश मान दे सकता है यदि इनपुट के रूप में इसे दी गई फ़ाइलों का क्रम बदल जाता है।

आपको md5sumकमांड md5या किसी अन्य हैश फ़ंक्शन को बदलने की आवश्यकता हो सकती है । यदि आप एक और हैश फ़ंक्शन चुनते हैं और आपके सिस्टम के लिए कमांड के दूसरे रूप की आवश्यकता होती है, तो आपको sortकमांड को तदनुसार समायोजित करने की आवश्यकता हो सकती है । एक और जाल यह है कि कुछ डेटा योग कार्यक्रमों में फ़ाइल का नाम बिल्कुल नहीं लिखा जाता है, एक प्रमुख उदाहरण पुराना यूनिक्स sumकार्यक्रम है।

यह विधि कुछ हद तक अक्षम है, जिसमें md5sumN + 1 बार कॉल किया जाता है , जहां N पेड़ में फ़ाइलों की संख्या है, लेकिन हैशिंग फ़ाइल और निर्देशिका मेटाडेटा से बचने के लिए यह आवश्यक लागत है।

विकल्प 2: डेटा और मेटाडेटा की तुलना करें

यदि आपको यह पता लगाने में सक्षम होना चाहिए कि पेड़ में कुछ भी नहीं बदला है, न कि केवल फ़ाइल सामग्री, tarनिर्देशिका सामग्री को आपके लिए पैक करने के लिए कहें , तो इसे भेजें md5sum:

$ tar -cf - somedir | md5sum

क्योंकि tarफ़ाइल अनुमतियाँ, स्वामित्व आदि को भी देखता है, यह उन चीज़ों में परिवर्तन का पता लगाएगा, न कि केवल फ़ाइल सामग्री में परिवर्तन।

यह विधि काफी तेज है, क्योंकि यह केवल एक पेड़ के ऊपर से गुजरती है और केवल एक बार हैश प्रोग्राम चलाती है।

findउपरोक्त विधि के साथ के रूप में , tarफाइल के नाम को संसाधित करने जा रहा है ताकि अंतर्निहित फाइल सिस्टम उन्हें वापस लौटाए। यह अच्छी तरह से हो सकता है कि आपके आवेदन में, आप यह सुनिश्चित कर सकते हैं कि आप ऐसा नहीं करेंगे। मैं कम से कम तीन अलग-अलग उपयोग पैटर्न के बारे में सोच सकता हूं जहां ऐसा होने की संभावना है। (मैं उन्हें सूचीबद्ध नहीं करने जा रहा हूं, क्योंकि हम अनिर्दिष्ट व्यवहार क्षेत्र में हो रहे हैं। प्रत्येक फाइल सिस्टम यहां ओएस के एक संस्करण से दूसरे तक भी अलग हो सकता है।)

यदि आप अपने आप को झूठी सकारात्मकता पाते हैं, तो मैं गिल्स के उत्तरfind | cpio में विकल्प के साथ जाने की सलाह दूंगा


7
मुझे लगता है कि निर्देशिका की तुलना करना और find .इसके बजाय उपयोग करना सबसे अच्छा है find somedir। इस तरह से फ़ाइल नाम समान हैं जब खोजने के लिए विभिन्न पथ-चश्मा प्रदान करते हैं; यह मुश्किल हो सकता है :-)
अब्बाफी

क्या हमें फाइलों को भी छांटना चाहिए?
CMCDragonkai

@CMCDragonkai: आपका क्या मतलब है? पहले मामले में, हम करते हैं फ़ाइल नामों की सूची को सॉर्ट। दूसरे मामले में, हम जानबूझकर नहीं करते हैं क्योंकि पहले वाक्य में किसी भी चीज पर जोर देने का हिस्सा यह है कि एक निर्देशिका में फाइलों का क्रम बदल गया है, इसलिए आप कुछ भी छांटना नहीं चाहेंगे।
वॉरेन यंग

@ArrenYoung क्या आप थोड़ा और अच्छी तरह समझा सकते हैं कि विकल्प 2 हमेशा बेहतर क्यों नहीं है? यह तेज, सरल और अधिक क्रॉस-प्लेटफॉर्म लगता है। किस मामले में यह विकल्प 1 नहीं होना चाहिए?
रॉबिन विंसलो

विकल्प 1 विकल्प: find somedir -type f -exec sh -c "openssl dgst -sha1 -binary {} | xxd -p" \; | sort | openssl dgst -sha1सभी फ़ाइलनामों को अनदेखा करना चाहिए (नई
लाइनों के

38

चेकसम को एक स्ट्रिंग के रूप में फाइलों के निर्धारक और स्पष्ट प्रतिनिधित्व का होना चाहिए। नियतात्मक का अर्थ है कि यदि आप समान स्थानों पर एक ही फाइल रखते हैं, तो आपको एक ही परिणाम मिलेगा। अस्पष्ट का मतलब है कि फ़ाइलों के दो अलग-अलग सेटों में अलग-अलग अभ्यावेदन हैं।

डेटा और मेटाडेटा

फाइलों से युक्त एक संग्रह बनाना एक अच्छी शुरुआत है। यह एक स्पष्ट प्रतिनिधित्व है (जाहिर है, चूंकि आप संग्रह को निकालकर फ़ाइलों को पुनर्प्राप्त कर सकते हैं)। इसमें फ़ाइल मेटाडेटा जैसे दिनांक और स्वामित्व शामिल हो सकते हैं। हालाँकि, यह अभी तक सही नहीं है: एक संग्रह अस्पष्ट है, क्योंकि इसका प्रतिनिधित्व उस क्रम पर निर्भर करता है जिसमें फाइलें संग्रहीत की जाती हैं, और यदि संपीड़न पर लागू होती है।

एक समाधान उन्हें संग्रहित करने से पहले फ़ाइल नामों को क्रमबद्ध करना है। यदि आपके फ़ाइल नामों में नई लिंक नहीं हैं, तो आप find | sortउन्हें सूचीबद्ध करने के लिए चला सकते हैं, और उन्हें इस क्रम में संग्रह में जोड़ सकते हैं। ध्यान रखें कि अभिलेखागार निर्देशिकाओं में पुनरावृत्ति न करने के लिए कहे। यहाँ POSIX pax, GNU टार और cpio के उदाहरण हैं :

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

नाम और सामग्री केवल, कम तकनीक का तरीका

यदि आप केवल फ़ाइल डेटा को ध्यान में रखना चाहते हैं और मेटाडेटा नहीं, तो आप एक संग्रह बना सकते हैं जिसमें केवल फ़ाइल सामग्री शामिल है, लेकिन इसके लिए कोई मानक उपकरण नहीं हैं। फ़ाइल सामग्री को शामिल करने के बजाय, आप फ़ाइलों के हैश को शामिल कर सकते हैं। यदि फ़ाइल नामों में कोई नई सूची नहीं है, और केवल नियमित फाइलें और निर्देशिकाएं हैं (कोई प्रतीकात्मक लिंक या विशेष फाइलें नहीं), तो यह काफी आसान है, लेकिन आपको कुछ बातों का ध्यान रखने की आवश्यकता है:

{ 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

हम चेकसमों की सूची के अलावा एक निर्देशिका सूची भी शामिल करते हैं, अन्यथा खाली निर्देशिका अदृश्य होगी। फ़ाइल सूची को सॉर्ट किया गया है (एक विशिष्ट, प्रतिलिपि प्रस्तुत करने योग्य स्थान में - उस की याद दिलाने के लिए पीटर.ओ के लिए धन्यवाद)। echoदो भागों को अलग करता है (इसके बिना, आप कुछ खाली निर्देशिका बना सकते हैं जिसका नाम md5sumआउटपुट की तरह दिखता है जो साधारण फ़ाइलों के लिए भी गुजर सकता है)। हम लंबाई-विस्तार हमलों से बचने के लिए, फ़ाइल आकारों की एक सूची भी शामिल करते हैं ।

वैसे, एमडी 5 को पदावनत कर दिया जाता है। यदि यह उपलब्ध है, तो SHA-2 या कम से कम SHA-1 का उपयोग करने पर विचार करें।

नाम और डेटा, नामों में newlines का समर्थन

यहाँ ऊपर दिए गए कोड का एक प्रकार है जो फ़ाइल नामों को null बाइट्स से अलग करने के लिए GNU टूल्स पर निर्भर करता है। यह फ़ाइल नामों को नई सूची में शामिल करने की अनुमति देता है। GNU डाइजेस्ट यूटिलिटीज़ अपने आउटपुट में विशेष वर्णों को उद्धृत करती हैं, इसलिए अस्पष्ट अस्पष्टताएँ नहीं होंगी।

{ 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

अधिक मजबूत दृष्टिकोण

यहाँ एक न्यूनतम परीक्षणित पायथन लिपि है जो फाइलों के पदानुक्रम का वर्णन करते हुए हैश बनाती है। यह निर्देशिकाओं और फ़ाइल सामग्री को खातों में ले जाता है और प्रतीकात्मक लिंक और अन्य फ़ाइलों को अनदेखा करता है, और यदि कोई फ़ाइल नहीं पढ़ी जा सकती है तो एक घातक त्रुटि देता है।

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

ठीक है, यह काम करता है, धन्यवाद। लेकिन क्या कोई मेटाडेटा शामिल किए बिना इसे करने का कोई तरीका है? अभी मुझे केवल वास्तविक सामग्री के लिए इसकी आवश्यकता है।

LC_ALL=C sortविभिन्न वातावरणों से जाँच के बारे में ... (+ 1 btw)
पीटर

आपने इसके लिए एक संपूर्ण पायथन कार्यक्रम बनाया? धन्यवाद! यह वास्तव में उससे अधिक है जो मैंने उम्मीद की थी। :-) वैसे भी, मैं इन विधियों के साथ-साथ वॉरेन द्वारा नए विकल्प 1 की जांच करूंगा।

अच्छा उत्तर। LC_ALL=Cकई मशीनों और OS पर चलने पर सॉर्ट क्रम सेट करना आवश्यक है।
क्यूबेरिक

क्या cpio -o -मतलब है? क्या cpio डिफ़ॉल्ट रूप से stdin / out का उपयोग नहीं करता है? GNU cpio 2.12 का उत्पादनcpio: Too many arguments
जन टोज्नर

12

पर एक नज़र डालें md5deep । Md5deep की कुछ विशेषताएं जो आपको रूचि दे सकती हैं:

पुनरावर्ती ऑपरेशन - md5deep एक संपूर्ण निर्देशिका ट्री की पुनरावर्ती जांच करने में सक्षम है। यही है, किसी निर्देशिका में प्रत्येक फ़ाइल के लिए MD5 और प्रत्येक उपनिर्देशिका में प्रत्येक फ़ाइल के लिए कंप्यूट करें।

तुलना मोड - md5deep ज्ञात हैश की सूची को स्वीकार कर सकते हैं और उनकी तुलना इनपुट फ़ाइलों के एक सेट से कर सकते हैं। कार्यक्रम या तो उन इनपुट फ़ाइलों को प्रदर्शित कर सकता है जो ज्ञात हैश की सूची से मेल खाते हैं या जो मेल नहीं खाते हैं।

...


अच्छा है, लेकिन यह काम करने के लिए नहीं मिल सकता है, यह कहता है .../foo: Is a directory, क्या देता है?
कैमिलो मार्टिन

3
अपने आप में md5deep ओपी की समस्या को हल नहीं करता है क्योंकि यह समेकित md5sum को प्रिंट नहीं करता है, यह सिर्फ निर्देशिका में प्रत्येक फ़ाइल के लिए md5sum को प्रिंट करता है। उस ने कहा, आप md5deep के आउटपुट को md5sum कर सकते हैं - काफी नहीं जो ओपी चाहता था, लेकिन करीब है! वर्तमान निर्देशिका के लिए उदाहरण: md5deep -r -l -j0 . | md5sum(जहां -rपुनरावर्ती है, -lइसका अर्थ है "सापेक्ष पथों का उपयोग करें" ताकि दो निर्देशिकाओं की सामग्री की तुलना करने की कोशिश करते समय फाइलों का निरपेक्ष मार्ग हस्तक्षेप न करे, और -j0इसका अर्थ गैर-नियतात्मकता को रोकने के लिए 1 थ्रेड का उपयोग करें। अलग-अलग क्रमों में अलग-अलग md5sums को लौटाया जा रहा है)।
स्टीवी

पथ में कुछ फ़ाइलों / निर्देशिकाओं को अनदेखा कैसे करें?
संदीपन नाथ

9

यदि आपका लक्ष्य सिर्फ दो निर्देशिकाओं के बीच अंतर खोजना है, तो अंतर का उपयोग करने पर विचार करें।

इसे इस्तेमाल करे:

diff -qr dir1 dir2

हां, यह उपयोगी है। मुझे लगता है कि आपको उस कमांड में dir1 dir2 का मतलब था।

1
जब मैं उनसे बच सकता हूं, तो मैं आमतौर पर GUI का उपयोग नहीं करता हूं, लेकिन निर्देशिका के लिए kdiff3 महान है और कई प्लेटफार्मों पर भी काम करता है।
sinelaw

इस कमांड के साथ अलग-अलग फाइलें बताई गई हैं।
सर्ज स्ट्रोबंड्ट

7

आप प्रत्येक फ़ाइल को पुनरावर्ती रूप से हैश कर सकते हैं और फिर परिणामी पाठ को हैश कर सकते हैं:

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

md5deep आवश्यक है।


1
ubuntu 16.04 पर md5deepउपयोग के बजाय hashdeepक्योंकि md5deep पैकेज हैशदीप के लिए सिर्फ एक संक्रमणकालीन डमी है।
palik

1
मैंने हैशदीप की कोशिश की है। यह न केवल हैश बल्कि कुछ हेडर भी ## Invoked from: /home/myuser/dev/प्रस्तुत करता है , जिसमें आपका वर्तमान पथ और है ## $ hashdeep -s -r -l ~/folder/। यह सॉर्ट करने के लिए मिला, इसलिए यदि आप अपना वर्तमान फ़ोल्डर या कमांड लाइन बदलते हैं तो अंतिम हैश अलग होगा।
ट्रफ

3

फ़ाइल सामग्री केवल फ़ाइल नाम को छोड़कर

मुझे एक ऐसे संस्करण की आवश्यकता थी जो केवल फ़ाइल नाम की जाँच करता था क्योंकि सामग्री विभिन्न निर्देशिकाओं में रहती है।

इस संस्करण (वारेन यंग का जवाब) ने बहुत मदद की, लेकिन मेरे md5sumआउटपुट के फ़ाइलनाम का नाम (जिस पथ से मैंने कमांड चलाया था, उसके सापेक्ष), और फ़ोल्डर के नाम अलग-अलग थे, इसलिए भले ही अलग-अलग फ़ाइल चेकसम का मिलान हुआ हो, अंतिम चेकसम 'टी।

इसे ठीक करने के लिए, मेरे मामले में, मुझे केवल findआउटपुट की प्रत्येक पंक्ति से फ़ाइल नाम को हटाने की आवश्यकता थी (केवल पहले शब्द का उपयोग करके रिक्त स्थान द्वारा अलग किया गया cut):

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

आपको एक प्रतिलिपि प्रस्तुत करने योग्य सूची प्राप्त करने के लिए चेकसमों को क्रमबद्ध करने की आवश्यकता हो सकती है।
22:16

3

समाधान :

$ pip install checksumdir
$ checksumdir -a md5 assets/js
981ac0bc890de594a9f2f40e00f13872
$ checksumdir -a sha1 assets/js
88cd20f115e31a1e1ae381f7291d0c8cd3b92fad

तेजी से और आसान समाधान काम करता है तो पटकथा को मारना।

doc देखें: https://pypi.python.org/pypi/checksumdir/1.0.5


यदि आपके पास पाइप नहीं है, तो आपको इसे yum -y install python-pip (or dnf / apt-get) के साथ इंस्टॉल करने की आवश्यकता हो सकती है
दिमित्रीस्मेनोव

3

nix-hashसे निक्स पैकेज प्रबंधक

कमांड nix-hash प्रत्येक पथ की सामग्री के क्रिप्टोग्राफ़िक हैश की गणना करता है और इसे मानक आउटपुट पर प्रिंट करता है। डिफ़ॉल्ट रूप से, यह एक एमडी 5 हैश की गणना करता है, लेकिन अन्य हैश एल्गोरिदम भी उपलब्ध हैं। हैश हेक्साडेसिमल में छपा है।

हैश की गणना प्रत्येक पथ के क्रमांकन पर की जाती है: पथ में निहित फ़ाइल सिस्टम ट्री का एक डंप। यह निर्देशिकाओं और सिम्बलिंक्स को हैशड के साथ-साथ नियमित फ़ाइलों की अनुमति देता है। डंप एनएआर प्रारूप में निक्स-स्टोर - डंप द्वारा निर्मित है। इस प्रकार, nix-hash पथ nix-store --dump पथ के समान क्रिप्टोग्राफ़िक हैश प्राप्त करता है | md5sum।


2

मैं मध्यम संस्करणों के लिए अपने स्निपेट का उपयोग करता हूं :

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

और XXXL के लिए यह एक :

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


-xdevझंडा क्या करता है?
czerasz

यह आपको टाइप करने के लिए कहता है: man findऔर उस ठीक मैनुअल को पढ़ें;)
'12

अच्छी बात :-)। -xdev Don't descend directories on other filesystems.
czerasz

1
ध्यान दें कि यह नई, खाली फ़ाइलों (जैसे यदि आप किसी फ़ाइल को स्पर्श करते हैं) को अनदेखा करते हैं।
रॉनजॉन

ऐसे कई मामले हैं जहां यह पूरी तरह से अलग फ़ाइल और निर्देशिका संरचना के साथ एक ही md5sum का उत्पादन करेगा। फ़ाइलों और निर्देशिकाओं का नाम बदलना यह बिल्कुल भी नहीं बदलेगा कि अगर यह फ़ाइलों के क्रम को नहीं बदलता है। इसलिए मैं इस दृष्टिकोण की सिफारिश नहीं करूंगा।
हंस-पीटर स्टॉर्र

2

एक अच्छा ट्री चेक-योग गिट की ट्री-आईडी है।

दुर्भाग्य से कोई स्टैंड-अलोन टूल उपलब्ध नहीं है जो ऐसा कर सकता है (कम से कम मुझे यह पता नहीं है), लेकिन अगर आपके पास Git काम है तो आप एक नया रिपॉजिटरी सेट करने और उन फ़ाइलों को जोड़ने का दिखावा कर सकते हैं जिन्हें आप इंडेक्स की जांच करना चाहते हैं।

यह आपको (प्रतिलिपि प्रस्तुत करने योग्य) ट्री हैश का उत्पादन करने की अनुमति देता है - जिसमें केवल सामग्री, फ़ाइल नाम और कुछ कम फ़ाइल मोड (निष्पादन योग्य) शामिल हैं।


2

इस उत्कृष्ट उत्तर के अनुवर्ती के रूप में , यदि आप एक बड़ी निर्देशिका के लिए चेकसम की गणना में तेजी लाना चाहते हैं, तो GNU समानांतर की कोशिश करें :

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

(यह एक मैक का उपयोग कर रहा है md5, आवश्यकतानुसार बदलें।)

-kझंडा महत्वपूर्ण है, कि निर्देश देता है parallelअन्यथा समग्र राशि को चलाने के लिए भले ही फ़ाइलें सभी एक ही हैं चलाने पर बदल सकता है व्यवस्था बनाए रखने के। 100 तर्कों -n 100के md5साथ प्रत्येक उदाहरण को चलाने के लिए कहता है , यह एक पैरामीटर है जिसे आप सर्वश्रेष्ठ रन समय के लिए ट्वीक कर सकते हैं। (हालांकि मेरे व्यक्तिगत मामले में त्रुटि हुई थी) का -Xध्वज भी देखेंparallel


1

एक स्क्रिप्ट जो अच्छी तरह से जांच की जाती है और डुप्लिकेट खोजने, डेटा और मेटाडेटा दोनों पर तुलना करने, परिवर्धन के साथ-साथ परिवर्तन और निष्कासन सहित कई कार्यों का समर्थन करती है, आपको फ़िंगरप्रिंट पसंद हो सकता है ।

फ़िंगरप्रिंट अभी एक निर्देशिका के लिए एक एकल चेकसम का उत्पादन नहीं करता है, लेकिन एक ट्रांसक्रिप्ट फ़ाइल जिसमें उस निर्देशिका की सभी फ़ाइलों के लिए चेकसम शामिल हैं।

fingerprint analyze

यह index.fingerprintवर्तमान निर्देशिका में जनरेट करेगा जिसमें चेकसम, फ़ाइलनाम और फ़ाइल आकार शामिल हैं। डिफ़ॉल्ट रूप से यह दोनों का उपयोग करता है MD5और SHA1.256

भविष्य में, मैं फ़िंगरप्रिंट में मर्कल ट्रीज़ के लिए समर्थन जोड़ने की उम्मीद करता हूं जो आपको एक एकल शीर्ष-स्तरीय चेकसम प्रदान करेगा। अभी, आपको सत्यापन करने के लिए उस फ़ाइल को बनाए रखना होगा।


1

मैं नया निष्पादक नहीं चाहता था और न ही क्लंकी समाधान यहां मेरा लेना है:

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

एक मजबूत और स्वच्छ दृष्टिकोण

  • पहली चीजें पहले, उपलब्ध स्मृति हॉग मत करो! पूरी फाइल को फीड करने के बजाय किसी फाइल को चंक्स में रखें।
  • विभिन्न आवश्यकताओं / उद्देश्यों के लिए अलग-अलग दृष्टिकोण (सभी नीचे दिए गए या जो कभी लागू होते हैं, उन्हें चुनें):
    • डायरेक्ट्री ट्री में सभी प्रविष्टियों का केवल नाम दर्ज करें
    • सभी प्रविष्टियों की फ़ाइल सामग्री को हैश करें (जैसे मेटा, इनोड संख्या, समय, Atime, माइम, आकार, आदि को छोड़कर, आपको यह विचार मिलता है)
    • एक प्रतीकात्मक लिंक के लिए, इसकी सामग्री संदर्भ नाम है। इसे हैश करें या स्किप करना चुनें
    • प्रवेश की सामग्री का हैशिंग करते समय सिम्लिंक का पालन करें या उसका (सुलझा हुआ नाम) न करें
    • यदि यह एक निर्देशिका है, तो इसकी सामग्री केवल निर्देशिका प्रविष्टियाँ हैं। पुनरावर्ती रूप से ट्रेस करते समय उन्हें अंततः हैश किया जाएगा, लेकिन क्या इस स्तर की डायरेक्टरी प्रविष्टि के नाम इस निर्देशिका को टैग करने के लिए हैशेड होना चाहिए? उपयोग के मामलों में सहायक जहां हैश को सामग्री को हैश करने के लिए गहराई से आघात किए बिना एक बदलाव को जल्दी से पहचानने की आवश्यकता होती है। एक उदाहरण एक फ़ाइल का नाम परिवर्तन होगा, लेकिन बाकी सामग्री समान हैं और वे सभी काफी बड़ी फाइलें हैं
    • बड़ी फ़ाइलों को अच्छी तरह से संभाल लें (फिर से, मन राम)
    • बहुत गहरी निर्देशिका पेड़ों को संभालें (खुले फ़ाइल विवरणकों को ध्यान में रखें)
    • गैर मानक फ़ाइल नाम संभालें
    • सॉकेट, पाइप / फीफो, ब्लॉक डिवाइसेस, चार डिवाइसेस वाली फ़ाइलों के साथ कैसे आगे बढ़ें? उन्हें भी हैश करना चाहिए?
    • ट्रैवर्स करते समय किसी भी प्रविष्टि के एक्सेस समय को अपडेट न करें क्योंकि यह कुछ उपयोग मामलों के लिए साइड इफेक्ट और काउंटर-उत्पादक (सहज) होगा।

यह वही है जो मेरे सिर के ऊपर है, किसी भी व्यक्ति ने जो इस व्यावहारिक रूप से काम करने में कुछ समय बिताया है, उसने अन्य गोचरों और कोने के मामलों को पकड़ा होगा।

यहां एक उपकरण है (अस्वीकरण: मैं इसमें योगदानकर्ता हूं) dtreetrawl , मेमोरी पर बहुत हल्का है, जो अधिकांश मामलों को संबोधित करता है, किनारों के आसपास थोड़ा मोटा हो सकता है लेकिन काफी मददगार रहा है।

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

एक उदाहरण मानव अनुकूल उत्पादन:

...
... //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

सामान्य सलाह का हमेशा स्वागत है लेकिन सबसे अच्छे उत्तर विशिष्ट हैं और कोड के साथ जहां उपयुक्त हो। यदि आपके पास आपके द्वारा संदर्भित टूल का उपयोग करने का अनुभव है तो कृपया इसे शामिल करें।
bu5hman

@ bu5hman ज़रूर! जब तक मैं इसके विकास में शामिल नहीं हुआ हूं, तब तक मैं यह कहकर (आराम से) काफी आराम से काम कर रहा था।
छह-के

0

प्रत्येक निर्देशिका में सभी फ़ाइलों के लिए व्यक्तिगत रूप से करना।

# 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 आर्काइव फॉर्मेट में माइग्रेशन GNU Tar आधारित चेकसम को प्रभावित करता है

यह उत्तर कुछ समय पहले वारेन यंग और गिल्स के उत्कृष्ट उत्तरों में प्रस्तावित (अन्य बातों के अलावा) के लिए टार आउटपुट का उपयोग करने के दृष्टिकोण के पूरक अद्यतन के रूप में किया गया है ।

तब से, कम से कम ओपनएसयूएसई (इसके रिलीज़ 12.2 के बाद से) ने अपने जीएनयू टार प्रारूप को "जीएनयू टार 1.13.x प्रारूप" से (थोड़ा) बेहतर "पॉसिक्स 1003.1-2001 (पैक्स) प्रारूप" में बदल दिया । इसके अलावा अपस्ट्रीम (ग्नू टार के डेवलपर्स के बीच) वे एक ही माइग्रेशन करने के लिए चर्चा करते हैं, उदाहरण के लिए ग्नू टार मैनुअल के इस पृष्ठ पर अंतिम पैराग्राफ देखें :

जीएनयू टार के लिए डिफ़ॉल्ट प्रारूप को संकलन समय पर परिभाषित किया गया है। आप इसे चलाकर tar --helpऔर इसके आउटपुट की अंतिम पंक्तियों की जांच करके देख सकते हैं । आमतौर पर, जीएनयू टार को gnuप्रारूप में अभिलेखागार बनाने के लिए कॉन्फ़िगर किया गया है, हालांकि, भविष्य का संस्करण बदल जाएगा posix

(यह पृष्ठ विभिन्न संग्रह प्रारूपों पर भी अच्छी समीक्षा देता है जो GNU Tar के साथ उपलब्ध हैं।)

हमारे मामले में, जहां हम निर्देशिका सामग्री को टारगेट करते हैं और परिणाम होता है, और विशिष्ट उपाय किए बिना, GNU से POSIX प्रारूप में परिवर्तन के निम्नलिखित परिणाम होते हैं:

  • समान निर्देशिका सामग्रियों के बावजूद, परिणामी चेकसम भिन्न होगा।

  • समान निर्देशिका सामग्री के बावजूद, परिणामी चेकसम रन से चलाने के लिए अलग होगा यदि डिफ़ॉल्ट पैक्स हेडर का उपयोग किया जाता है।

उत्तरार्द्ध इस तथ्य से आता है, कि पोसिक्स (पैक्स) प्रारूप में विस्तारित पैक्स हेडर शामिल हैं जो कि %d/PaxHeaders.%p/%fजीएनयू टार में चूक वाले एक प्रारूप स्ट्रिंग द्वारा निर्धारित किए जाते हैं । इस स्ट्रिंग के भीतर, विनिर्देशक %pको जनरेटिंग टार प्रक्रिया की प्रक्रिया आईडी द्वारा बदल दिया जाता है, जो निश्चित रूप से रन से अलग है। देखें इस खंड की जीएनयू राल मैनुअल और विशेष रूप से यह एक जानकारी के लिए।

बस अब, 2019-03-28 से डेटिंग, इस मुद्दे को धता बताने वाली एक प्रतिबद्ध अपस्ट्रीम है।

इसलिए, दिए गए उपयोग के मामले में जीएनयू टार का उपयोग जारी रखने में सक्षम होने के लिए, मैं निम्नलिखित वैकल्पिक विकल्पों की सिफारिश कर सकता हूं:

  • --format=gnu"पुराने" प्रारूप में संग्रह उत्पन्न करने के लिए टार को स्पष्ट रूप से बताने के लिए टार विकल्प का उपयोग करें । यह "पुराने" चेकसमों को मान्य करने के लिए अनिवार्य है।

  • नए POSIX प्रारूप का उपयोग करें, लेकिन स्पष्ट रूप से एक उपयुक्त पैक्स हैडर निर्दिष्ट करें, उदाहरण के लिए --pax-option="exthdr.name=%d/PaxHeaders/%f"। हालांकि, यह "पुराने" चेकसमों के लिए पिछड़ी संगतता को तोड़ता है।

यहाँ एक बैश कोड टुकड़ा है जो मैं नियमित रूप से मेटाडेटा सहित निर्देशिका सामग्री के चेकसम की गणना के लिए उपयोग करता हूं:

( 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; )

इसके अलावा, <paths>सभी निर्देशिकाओं के रास्तों की एक अंतरिक्ष से अलग सूची द्वारा प्रतिस्थापित किया जाता है जिसे मैं चेकसम द्वारा कवर करना चाहता हूं। सी लोकेल का उपयोग करने का उद्देश्य, फाइलनामों की अशक्त बाइट अलग करना, और संग्रह में फ़ाइलों के स्वतंत्र क्रम को एक फाइल सिस्टम प्राप्त करने के लिए खोज और सॉर्ट का उपयोग करना पहले से ही अन्य उत्तरों में पर्याप्त रूप से चर्चा में है।

आसपास के कोष्ठक LC_ALLसेटिंग को स्थानीय स्तर पर रखते हैं।

इसके अलावा, मैं अभिव्यक्ति का उपयोग ! -type sके साथ findराल से चेतावनी है कि हो अगर सॉकेट फ़ाइलें निर्देशिका सामग्री का हिस्सा हैं से बचने के लिए: जीएनयू राल नहीं है संग्रह सॉकेट। यदि आप स्किप किए गए सॉकेट के बारे में सूचित होना पसंद करते हैं, तो उस अभिव्यक्ति को छोड़ दें।

मैं --numeric-ownerटार के साथ उपयोग करता हूं , सिस्टम पर बाद में भी चेकसमों को सत्यापित करने में सक्षम होने के लिए, जहां सभी फ़ाइल मालिकों को नहीं जाना जाता है।

--atime-preserveराल के लिए विकल्प बेहतर है, तो छोड़ दिया जाता है की किसी भी <paths>एक केवल पढ़ने के लिए घुड़सवार डिवाइस पर निहित है। अन्यथा आपको प्रत्येक एकल फ़ाइल के लिए चेतावनी दी जाएगी जिसकी पहुंच टाइमस्टैम्प टार को बहाल करने में सक्षम नहीं थी। सक्षम लिखने के लिए <paths>, मैं इस विकल्प का उपयोग करता हूं, अच्छी तरह से, हैशेड निर्देशिका में एक्सेस टाइमस्टैम्प को संरक्षित करने के लिए।

टार विकल्प --no-recursion, जो पहले से ही गिल्स के प्रस्ताव में इस्तेमाल किया गया था , टार को अपने द्वारा निर्देशिकाओं में पुनरावर्ती वंश से रोकता है, और सॉर्ट किए गए findआउटपुट से जो भी प्राप्त होता है, उस पर फ़ाइल द्वारा फ़ाइल के बजाय काम करने के लिए ।

और अंत में, यह सच नहीं है कि मैं उपयोग करता हूं md5sum: मैं वास्तव में उपयोग करता हूं sha256sum


-1

यदि आपको md5 की आवश्यकता नहीं है, तो आप कोशिश कर सकते हैं

find . -type f | xargs cksum | cksum

1
प्रश्न विशेष रूप से md5 के लिए पूछता है
RalfFriedl
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.