2013-05-27 11 views
12

पर md5sum चेकसम parallelize की सुविधा देता है कहते हैं, मैं एक 64-कोर सर्वर है, और मैं /mnt/data में सभी फाइलों की md5sum गणना, और एक पाठ फ़ाइल में परिणाम स्टोर करने के लिए की जरूरत है:बैश: कई फाइलों

find /mnt/data -type f -exec md5sum {} \; > md5.txt 

उपरोक्त आदेश के साथ समस्या यह है कि किसी भी समय केवल एक प्रक्रिया चलती है। मैं अपने 64-कोर की पूरी शक्ति का उपयोग करना चाहता हूं। आदर्श रूप से, मैं यह सुनिश्चित करना चाहता हूं कि किसी भी समय, 64 समांतर md5 प्रक्रियाएं चल रही हैं (लेकिन 64 से अधिक नहीं)।

भी। मुझे एक प्रक्रिया में सभी प्रक्रियाओं से आउटपुट की आवश्यकता होगी।

नोट: मैं समानांतर में एक फ़ाइल के md5sum की गणना करने का कोई तरीका नहीं ढूंढ रहा हूं। मैं समानांतर में 64 विभिन्न फ़ाइलों के 64 एमडी 5 एसएमएस की गणना करने का एक तरीका ढूंढ रहा हूं, जब तक find से कोई भी फाइल आ रही है।

+5

मुझे यकीन नहीं है कि यह अच्छा होगा। मैं कल्पना कर सकता हूं कि सामान आईओ बहुत जल्द हो गया है और 64 प्रक्रियाओं का उपयोग करने से आईओओ धीमा हो जाएगा जबकि कई कोर निष्क्रिय हो जाएंगे। – glglgl

+0

लेकिन दूसरी तरफ, आधुनिक फाइल सिस्टम रैम में बहुत कैश किए जाते हैं, इसलिए एक समय में एक से अधिक का उपयोग करना समझ में आता है। – Alfe

+1

@Alfe: कर्नेल को अभी भी * RAM * डेटा प्राप्त करना होगा, इसलिए बाधा बनी हुई है। –

उत्तर

16

GNU parallel का उपयोग करें। और आप here को कार्यान्वित करने के तरीके पर कुछ और उदाहरण पा सकते हैं।

find /mnt/data -type f | parallel -j 64 md5sum > md5.txt 
+1

मुझे जीएनयू समानांतर नहीं पता था। इसका जिक्र करने के लिए धन्यवाद। मुझे यह देखना होगा कि यह मेरे मामले में उपयोगी है या नहीं। फिलहाल, समय ढूंढें/mnt/data -type f | समानांतर -j 16 md5sum> md5.txt' सामान्य खोज से लगभग 3 गुना धीमा है 'समय ढूंढें/usr/share -type f -exec md5sum {} \; > md5.txt'। – user1968963

1

UPDATED

आप आप इस तरह sg कोशिश कर सकते हैं अतिरिक्त संकुल का उपयोग नहीं करना चाहते हैं:

#!/usr/bin/bash 

max=5; 
cpid=() 

# Enable job control to receive SIGCHLD 
set -m 
remove() { 
    for i in ${!cpid[*]}; do 
    [ ! -d /proc/$i ] && echo UNSET $i && unset cpid[$i] && break 
    done 
} 
trap remove SIGCHLD 

for x in $(find ./ -type f -name '*.sh'); do 
    some_long_process $x& 
    cpid[$!]="$x"; 
    while [ ${#cpid[*]} -ge $max ]; do 
    echo DO SOMETHING && sleep 1; 
    done 
done 
wait 

यह पहली बार है, तो एक उपप्रक्रिया बाहर निकलता है SIGCHLD प्राप्त करने के लिए सक्षम बनाता है। अगर सिग्चाल्ड को पहली गैर-मौजूदा प्रक्रिया मिलती है और cpid सरणी से हटा दी जाती है।

फॉर-लूप में यह maxsome_long_process प्रक्रियाओं को असीमित रूप से शुरू करता है। यह maxcpid सरणी में जोड़े गए सभी बोलियों के चुनावों तक पहुंच गया। यह cpid की लंबाई max से कम है और कुछ और प्रक्रियाओं को असंकालिक रूप से शुरू करता है।

यदि सूची खत्म हो गई है तो यह सभी बच्चों को समाप्त करने की प्रतीक्षा करता है।

जोड़ा

अंत में मैं एक उचित समाधान here मिल गया है।

+0

लिपि के लिए धन्यवाद। दुर्भाग्य से, यह कोई सुधार नहीं लाता है। दरअसल, समय सरल खोज के मुकाबले लंबा है। इसके अलावा, अधिकांश कोर निष्क्रिय होने लगते हैं। मुझे प्रयोग करना होगा, अगर मैं इसे बदल सकता हूं। – user1968963

+0

@ user1968963: शायद 'नींद 1' लाइन हटा दी जा सकती है। यह अनावश्यक रूप से एक कोर लोड करेगा। उस तरह से कोशिश करो। हो सकता है कि आप 'find/mnt/data -type f -exec md5sum {} +> md5.txt' का उपयोग करके थोड़ा सा सुधार कर सकें। ';' के बजाय पीछे की ओर '+ 'मन करें! यह 'md5sum' बहुत कम बार कॉल करेगा। (देखें '-exec कमांड {} + 'में [ढूंढें (1)] (http://linux.die.net/man/1/find))। – TrueY

6

यदि आप प्रयोग चाहते हैं तो md5deep इंस्टॉल करने का प्रयास करें। (http://md5deep.sourceforge.net)

Here is the manual जहां पढ़ सकते हैं:

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

यह नहीं मदद करता है, तो निष्क्रिय करने के लिए -j0 निर्दिष्ट करते हैं, आप आई/ओ टोंटी की है।

4

आप xargs का भी उपयोग कर सकते हैं, यह कुछ distro पर समानांतर से अधिक उपलब्ध हो सकता है।

-P प्रक्रिया की संख्या को नियंत्रित करता है।

find /mnt/data -type f | xargs -L1 -P24 md5sum > /tmp/result.txt 
+1

जब भी फ़ाइल नामों में रिक्त स्थान होते हैं तो प्रदान किया गया उत्तर काम नहीं करता है। सही एक निम्न है, POSIX स्विच का भी उपयोग कर रहा है: "ढूंढें/mnt/data -type f -print0 | xargs -L1 -P24 -0 md5> /tmp/result.txt" आप भी उपयोग करना चाहेंगे आउटपुट को आउटपुट करने के लिए md5 के लिए विकल्प- और पथ से पहले चेकसम प्राप्त करें, ताकि आप चेकसम द्वारा ऑर्डर कर सकें और आसानी से डुप्लीकेट ढूंढ सकें। – FarO

+1

@ ओलाफएम मैंने पहले से ही उस मुद्दे को ठीक किया है, जैसा कि आप देख सकते हैं। – Braiam

+0

@ ब्रायम यह अभी भी रिक्त स्थान वाले फ़ाइल नामों पर काम नहीं करेगा। उन लोगों को विशेष रूप से "-प्रिंट 0" और "-0" की आवश्यकता होती है जो आउटपुट को विभाजित करने के लिए नहीं होते हैं (सफेद रूप से फ़ाइल नामों के भीतर) लेकिन शून्य वर्णों के अनुसार। – FarO

संबंधित मुद्दे