2012-03-09 6 views
5

अद्यतन: एक ओर जहां वास्तव में मेरे पाइपिंग प्रयासों के संबंध में प्रस्तुत मूल समस्या को हल करने नहीं, मैं मेरी समस्या हल कर लिया है इसे बहुत सरल बनाकर, और केवल पाइप को पूरी तरह से डुबोकर। डिस्क, सीआरसी 32, एमडी 5, एसएचए 1, एसएचए 224, एसएचए 256, एसएचए 384, और एसएचए 512 चेकसम, और उन्हें जेएसओएन ऑब्जेक्ट के रूप में लौटने के दौरान समानांतर में, एक सबूत-ऑफ-अवधारणा स्क्रिप्ट है, जो PHP में आउटपुट का उपयोग करेगी और रूबी)। यह त्रुटि जाँच के बिना कच्चे तेल है, लेकिन यह काम करता है:एक bash स्क्रिप्ट में एक नामित पाइप पर पहुंचने के बाहर के अनुक्रम कई टी प्राप्तकर्ताओं से पाइप उत्पादन के साथ संभव रेस स्थिति

#!/bin/bash 

checksums="`tee <"$1" \ 
     >(cfv -C -q -t sfv -f - - | tail -n 1 | sed -e 's/^.* \([a-fA-F0-9]\{8\}\)$/"crc32":"\1"/') \ 
     >(md5sum - | sed -e 's/^\([a-fA-F0-9]\{32\}\) .*$/"md5":"\1"/') \ 
     >(sha1sum - | sed -e 's/^\([a-fA-F0-9]\{40\}\) .*$/"sha1":"\1"/') \ 
     >(sha224sum - | sed -e 's/^\([a-fA-F0-9]\{56\}\) .*$/"sha224":"\1"/') \ 
     >(sha256sum - | sed -e 's/^\([a-fA-F0-9]\{64\}\) .*$/"sha256":"\1"/') \ 
     >(sha384sum - | sed -e 's/^\([a-fA-F0-9]\{96\}\) .*$/"sha384":"\1"/') \ 
     >(sha512sum - | sed -e 's/^\([a-fA-F0-9]\{128\}\) .*$/"sha512":"\1"/') \ 
     >/dev/null`\ 
" 

json="{" 

for checksum in $checksums; do json="$json$checksum,"; done 

echo "${json:0: -1}}" 

मूल प्रश्न:

मैं थोड़ा इस सवाल पूछने के लिए, के रूप में मैं अपने खोज वाक्यांश पर इतने सारे हिट मिल गया है कि आवेदन करने के बाद डर लग रहा है ज्ञान Using named pipes with bash - Problem with data loss से कटाई, और एक और 20 पृष्ठों के माध्यम से पढ़ना, मैं अभी भी इसके साथ एक स्टैंड-स्टिल पर हूं।

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

मूल रूप से, मैंने बस एक साधारण लिपि को एक साथ हैक किया था जिसमें तीन सीएफवी कमांडों के साथ टीई को फाइल करने के लिए फ़ाइल को लिखा था, जो तीन अलग-अलग फाइलों को/tmp/के अंतर्गत लिखते थे, और फिर उन्हें बाद में बाहर निकलने के लिए बाहर निकालने का प्रयास किया गया, लेकिन समाप्त हो गया खाली आउटपुट के साथ जब तक कि मैंने फ़ाइलों को पढ़ने की कोशिश करने से पहले एक सेकंड के लिए अपनी स्क्रिप्ट नींद नहीं की। यह सोचकर कि अजीब था, मुझे लगता है कि मैं अपनी पटकथा में एक मूर्खतापूर्ण था, इसलिए मैंने सीएफवी श्रमिकों को नामित पाइप पर आउटपुट करके एक अलग दृष्टिकोण करने की कोशिश की। अब तक, इस मेरी स्क्रिप्ट, है forementioned लिंक से लागू किया तकनीक होने के बाद:

[email protected]:~/tisso$ ./multisfv file 
: : : quitting now 
- : Broken pipe (CF) 
close failed in file object destructor: 
sys.excepthook is missing 
lost sys.stderr 
- : Broken pipe (CF) 
close failed in file object destructor: 
sys.excepthook is missing 
lost sys.stderr 
- : Broken pipe (CF) 
[email protected]:~/tisso$ close failed in file object destructor: 
sys.excepthook is missing 
lost sys.stderr 

लेकिन, बाहर टिप्पणी की नींद 1s के साथ:

!/bin/bash 

# Bail out if argument isn't a file: 
[ ! -f "$1" ] && echo "'$1' is not a file!" && exit 1 

# Choose a name for a pipe to stuff with CFV output: 
pipe="/tmp/pipe.chksms" 

# Don't leave an orphaned pipe on exiting or being terminated: 
trap "rm -f $pipe; exit" EXIT TERM 

# Create the pipe (except if it already exists (e.g. SIGKILL'ed b4)): 
[ -p "$pipe" ] || mkfifo $pipe 

# Start a background process that reads from the pipe and echoes what it 
# receives to stdout (notice the pipe is attached last, at done): 
while true; do 
     while read line; do 
       [ "$line" = "EOP" ] && echo "quitting now" && exit 0 
       echo "$line" 
     done 
done <$pipe 3>$pipe & # This 3> business is to make sure there's always 
         # at least one producer attached to the pipe (the 
         # consumer loop itself) until we're done. 

# This sort of works without "hacks", but tail errors out when the pipe is 
# killed, naturally, and script seems to "hang" until I press enter after, 
# which I believe is actually EOF to tail, so it's no solution anyway: 
#tail -f $pipe & 

tee <"$1" >(cfv -C -t sfv -f - - >$pipe) >(cfv -C -t sha1 -f - - >$pipe) >(cfv -C -t md5 -f - - >$pipe) >/dev/null 

#sleep 1s 
echo "EOP" >$pipe 
exit 

तो, मार डाला के रूप में यह खड़ा है, मैं इस आउटपुट प्राप्त , मैं उम्मीद करने के उत्पादन,

[email protected]:~/tisso$ ./multisfv file 
3bc1b5ff125e03fb35491e7d67014a3e * 
-: 1 files, 1 OK. 0.013 seconds, 79311.7K/s 
5e3bb0e3ec410a8d8e14fef1a6daababfc48c7ce * 
-: 1 files, 1 OK. 0.016 seconds, 62455.0K/s 
; Generated by cfv v1.18.3 on 2012-03-09 at 23:45.23 
; 
2a0feb38 
-: 1 files, 1 OK. 0.051 seconds, 20012.9K/s 
quitting now 

यह पहेली मुझे, प्रत्येक CFV प्राप्तकर्ता के बाद यह कांटे डेटा तक बाहर निकलने नहीं के रूप में मुझे लगता है कि टी मान था बाहर निकल गया है होता है, और इस प्रकार गूंज "EOP" बयान होगा भूतपूर्व जब तक सभी सीएफवी सबस्ट्रीम समाप्त नहीं हो जाते हैं, तो इसका अर्थ यह होगा कि वे अपने आउटपुट पाइप पर अपना आउटपुट लिख चुके होंगे ... और फिर गूंज कथन निष्पादित होगा।

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

कोई विचार?

TIA, डैनियल :) एक बार यह पिछले उत्पादन पाइप के लिए इनपुट के अंतिम बिट लिखते हैं और यह (बंद कर देता है

+1

मुझे उम्मीद है कि इन चेकसम के लिए स्रोत कोड उपलब्ध होगा। उन्हें 1 प्रोग्राम में संयोजित करने और 3 चेक लिखने के बारे में कैसे आप उचित चेकसम फ़ाइल में संसाधित करते हैं। मुझे विश्वास है कि पर्ल में शायद इसके लिए मॉड्यूल हैं, जो फिर से, आप फ़ाइल पर केवल 1 पास करने के लिए एक साथ ग्लोम कर सकते हैं। (बस इस पर बॉक्स के बारे में सोचते हुए, वाईआरएमवी)। सौभाग्य! – shellter

+1

क्या यह मदद करेगा? 'समांतर - समूह' cfv -C -t sfv -f {} -; cfv -C -t sha1 -f {} -; cfv-c -t md5 -f {} -; ' ::: फ़ाइल' – potong

+0

@ शेल्टर - मुझे लगता है कि मेरी खुद की दिनचर्या लिखना हमेशा मेरी फॉलबैक है, लेकिन मैं जितना संभव हो उतना पहले से उपलब्ध टूल का उपयोग करना पसंद करूंगा। – DanielSmedegaardBuus

उत्तर

2

टी बाहर निकल जाएगा कि है, अनाम बैश द्वारा बनाई गई पाइप, नहीं अपने फीफो, उर्फ ​​" नामित पाइप ")। पाइप को खत्म करने की प्रक्रियाओं की प्रतीक्षा करने की आवश्यकता नहीं है; वास्तव में, यह नहीं पता कि यह पाइप को भी लिख रहा है। चूंकि पाइपों में बफर होते हैं, इसलिए यह संभव है कि दूसरी छोर पर प्रक्रियाओं से पहले टी खत्म हो जाए, पढ़ना समाप्त हो गया हो। तो लिपि फीफो में 'ईओपी' लिखेगी, जिससे पठन लूप समाप्त हो जाएगा। इससे फीफो के एकमात्र पाठक को बंद कर दिया जाएगा, और जब वे अगली बार stdout लिखने का प्रयास करेंगे तो सभी सीएफवी प्रक्रियाओं को सिगिपिप मिलेगा।

यहां पूछने के लिए स्पष्ट सवाल यह है कि आप फ़ाइल को पढ़ने और विभिन्न सारांशों की गणना करने के लिए केवल तीन (या एन) स्वतंत्र प्रक्रियाओं को क्यों नहीं चलाते हैं। अगर फ्लाई पर "फ़ाइल" वास्तव में उत्पन्न की जा रही थी या कुछ रिमोट साइट से डाउनलोड की गई थी, या कुछ अन्य धीमी प्रक्रिया, तो चीजों को करने का तरीका हो सकता है जिस तरह से आप उन्हें करने की कोशिश कर रहे हैं, लेकिन यदि फ़ाइल स्थानीय पर मौजूद है डिस्क, यह काफी संभावना है कि वास्तव में केवल एक डिस्क पहुंच होगी; लैगिंग ग्रीष्मकालीन फाइल बफर कैश से फ़ाइल को पढ़ेगी। यदि आपको बस इतना ही चाहिए, तो जीएनयू समानांतर ठीक काम करना चाहिए, या आप बस प्रक्रियाओं को शुरू कर सकते हैं (& के साथ) और फिर उनके लिए प्रतीक्षा करें। वाईएमएमवी लेकिन मुझे लगता है कि इनमें से कोई भी समाधान उन सभी पाइपों को स्थापित करने और टीई के साथ उपयोगकर्तालैंड में बफर कैश को सिमुलेट करने से कम संसाधन-गहन होगा।

वैसे, यदि आप एकाधिक प्रक्रियाओं से आउटपुट को क्रमबद्ध करना चाहते हैं, तो आप झुंड उपयोगिता का उपयोग कर सकते हैं। बस एक फीफो का उपयोग पर्याप्त नहीं है; इस बात की कोई गारंटी नहीं है कि फीफो को लिखने वाली प्रक्रियाएं संपूर्ण रूप से पूरी लाइनें लिखेंगी और यदि आपको पता था कि उन्होंने ऐसा किया है, तो आपको फीफो की आवश्यकता नहीं होगी।

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