2011-09-30 12 views
9

के साथ "ढूंढें" और "एलएस" मैं वेब सर्वर पर बहुत सारी फाइलें पोस्ट करने के लिए GNU parallel का उपयोग करने का प्रयास कर रहा हूं। मेरी निर्देशिका में, मैं कुछ फ़ाइलें:जीएनयू समांतर

file1.xml 
file2.xml 

और मैं एक खोल स्क्रिप्ट है कि इस तरह दिखता है:

#! /usr/bin/env bash 

CMD="curl -X POST [email protected]$1 http://server/path" 

eval $CMD 

वहाँ लिपि में कुछ अन्य सामान है, लेकिन यह सबसे सरल उदाहरण था। मैं निम्न आदेश पर अमल करने की कोशिश की:

ls | parallel -j2 script.sh {} 

जो वह चीज़ GNU parallel पृष्ठों "सामान्य" जिस तरह से एक निर्देशिका में फ़ाइलों पर संचालित करने के लिए के रूप में दिखाई देते हैं। यह मेरी स्क्रिप्ट में फ़ाइल का नाम पारित करने के लिए लगता है, लेकिन कर्ल शिकायत है कि यह में पारित डेटा फ़ाइल लोड नहीं कर सकता फिर भी, अगर मैं ऐसा:।

find . -name '*.xml' | parallel -j2 script.sh {} 

यह ठीक काम करता है। क्या ls और find मेरी स्क्रिप्ट के लिए तर्क पारित करने के बीच कोई अंतर है? या मुझे उस स्क्रिप्ट में कुछ अतिरिक्त करने की ज़रूरत है?

+1

आप # के साथ चलने की कोशिश की!/ bin/bash -x जो आपको दिखाएगा कि क्या आपके तर्क नहीं हैं जो आपको लगता है कि वे होना चाहिए। –

+0

जब ऐसा होता है तो मैं हमेशा शर्मिंदा हूं, लेकिन जब मैंने अगले दिन इस मुद्दे को पुन: उत्पन्न करने की कोशिश की (और सुझाव के अनुसार -x का उपयोग करें) मैं इसे पुन: पेश नहीं कर सका और सबकुछ बढ़िया काम कर रहा था। मैं एलएस का उपयोग करने या हर बार सफलता के साथ खोजने में सक्षम हूं। मैं सोच रहा हूं कि क्या मैंने किसी भी तरह से अपने पर्यावरण को रोक दिया है और लॉग आउट/कुछ साफ़ कर दिया है। – Dave

उत्तर

2

मैंने parallel का उपयोग नहीं किया है, लेकिन ls & find . -name '*.xml' के बीच एक अलग है। lsसभी फाइलों और निर्देशिकाओं को सूचीबद्ध करेगा जहां find . -name '*.xml' केवल .xml के साथ समाप्त होने वाली फ़ाइलों (और निर्देशिका) सूचीबद्ध करेगा।
पॉल रूबेल द्वारा सुझाए गए अनुसार, इसे जांचने के लिए बस अपनी स्क्रिप्ट में $ 1 का मूल्य प्रिंट करें। इसके अतिरिक्त आप विकल्प के साथ केवल find में फ़ाइलों को इनपुट फ़िल्टर करने पर विचार करना चाह सकते हैं।
आशा है कि इससे मदद मिलती है!

1

साफ।

मैंने पहले कभी समानांतर उपयोग नहीं किया था। ऐसा लगता है, हालांकि उनमें से दो हैं। एक जीएनयू पैरारलल है, और मेरे सिस्टम पर स्थापित एक है जो टोललेफ फॉग हेन मैन पेजों में लेखक के रूप में सूचीबद्ध है।

पॉल के रूप में उल्लेख किया है, आप सेट -x

भी उपयोग करना चाहिए, प्रतिमान है कि आप ऊपर उल्लेख निम्न करने के लिए मेरी समानांतर पर काम प्रतीत नहीं होता है, बल्कि, मैं है:

$ cat ../script.sh 
+ cat ../script.sh 
#!/bin/bash 
echo [email protected] 
$ parallel -ij2 ../script.sh {} -- $(find -name '*.xml') 
++ find -name '*.xml' 
+ parallel -ij2 ../script.sh '{}' -- ./b.xml ./c.xml ./a.xml ./d.xml ./e.xml 
./c.xml 
./b.xml 
./d.xml 
./a.xml 
./e.xml 
$ parallel -ij2 ../script.sh {} -- $(ls *.xml) 
++ ls --color=auto a.xml b.xml c.xml d.xml e.xml 
+ parallel -ij2 ../script.sh '{}' -- a.xml b.xml c.xml d.xml e.xml 
b.xml 
a.xml 
d.xml 
c.xml 
e.xml 

खोज एक अलग इनपुट प्रदान करता है, यह नाम के सापेक्ष पथ को प्रस्तुत करता है। हो सकता है कि आपकी स्क्रिप्ट को गड़बड़ कर रहा हो?

5

जीएनयू parallelxargs का एक संस्करण है। दोनों में बहुत समान इंटरफेस हैं, और यदि आप parallel पर सहायता की तलाश में हैं, तो आपको xargs के बारे में जानकारी देखने में अधिक भाग्य हो सकता है।

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

यहाँ एक उदाहरण है:

> echo "foo bar \ 
    baz" | xargs echo 
foo bar baz 

डिफ़ॉल्ट व्यवहार के साथ कुछ समस्याएं हैं, तो यह कई रूप देखने के लिए आम बात है।

पहला मुद्दा यह है कि व्हाइटसाइट का उपयोग टोकननाइज करने के लिए किया जाता है, इसलिए उनमें सफेद जगह वाली किसी भी फाइल समानांतर और xargs को तोड़ने का कारण बनती है। एक समाधान इसके बजाय नल चरित्र के चारों ओर टोकननाइज करना है। find भी यह आसान करने के लिए बनाने के लिए एक विकल्प प्रदान करता है:

> echo "Success!" > bad\ filename 
> find . "bad\ filename" -print0 | xargs -0 cat 
Success! 

-print0 विकल्प find बताता शून्य चरित्र के बजाय सफेद स्थान के साथ फ़ाइलें अलग करने के।
-0 विकल्प प्रत्येक तर्क को टोकन करने के लिए नल चरित्र का उपयोग करने के लिए xargs बताता है।

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

एक और आम मुद्दा यह है कि आप यह नियंत्रित करना चाहते हैं कि xargs या parallel पर तर्क कैसे पारित किए जाते हैं। यदि आपको प्रोग्राम में दिए गए तर्कों का एक विशिष्ट प्लेसमेंट होना आवश्यक है, तो आप यह निर्धारित करने के लिए {} का उपयोग कर सकते हैं कि तर्क कहां रखा जाना है।

> mkdir new_dir 
> find -name *.xml | xargs mv {} new_dir 

यह सभी फ़ाइलों को वर्तमान निर्देशिका और उपनिर्देशिका में new_dir निर्देशिका में स्थानांतरित करेगा। यह वास्तव में निम्नलिखित में टूट जाती है:

> find -name *.xml | xargs echo mv {} new_dir 
> mv foo.xml new_dir 
> mv bar.xml new_dir 
> mv baz.xml new_dir 

तो ध्यान में ले जा रहा है कि कैसे xargs और parallel काम करते हैं, आप उम्मीद है कि अपने आदेश के साथ इस मुद्दे को देखने के लिए सक्षम होना चाहिए। find . -name '*.xml'script.sh प्रोग्राम में पास होने के लिए एक्सएमएल फाइलों की एक सूची उत्पन्न करेगा।

> find . -name '*.xml' | parallel -j2 echo script.sh {} 
> script.sh foo.xml 
> script.sh bar.xml 
> script.sh baz.xml 

हालांकि, ls | parallel -j2 script.sh {} script.sh कार्यक्रम को पास करने की मौजूदा निर्देशिका में सभी फ़ाइलों की एक सूची उत्पन्न होगा। ls संस्करण पर

> ls | parallel -j2 echo script.sh {} 
> script.sh some_directory 
> script.sh some_file 
> script.sh foo.xml 
> ... 

एक अधिक सही संस्करण के रूप में निम्नानुसार होगा:

> ls *.xml | parallel -j2 script.sh {} 

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

> find -maxdepth 1 -name '*.xml' 

यह केवल वर्तमान निर्देशिका खोज करेंगे: उपरोक्त ls आदेश के बराबर find संस्करण निम्नानुसार होगा।

3

चूंकि यह find के साथ काम करता है, तो शायद आप देखना चाहते हैं कि जीएनयू समांतर चल रहा है (-v या --dryrun का उपयोग करके) और फिर असफल आदेशों को मैन्युअल रूप से चलाने का प्रयास करें।

ls *.xml | parallel --dryrun -j2 script.sh 
find -maxdepth 1 -name '*.xml' | parallel --dryrun -j2 script.sh