एक प्रक्रिया से दूसरी प्रक्रिया में पाई जाने वाली बाइट्स की गिनती


17

मैं एक शेल स्क्रिप्ट चला रहा हूं जो एक प्रक्रिया से दूसरी प्रक्रिया में डेटा को पाइप करता है

process_a | process_b

क्या किसी को यह पता लगाने का एक तरीका है कि दो कार्यक्रमों के बीच कितने बाइट्स पारित किए गए थे? एकमात्र समाधान जो मैं इस समय सोच सकता हूं कि एक छोटा सी प्रोग्राम लिखना होगा जो स्टडिन से पढ़ता है, स्टैडआउट को लिखता है और स्थानांतरित किए गए सभी डेटा को काउंट करता है, काउंट को एक पर्यावरण चर में संग्रहीत करता है, जैसे:

process_a | count_bytes | process_b

क्या किसी के पास खाने का हल है?

जवाबों:


16

डीडी के माध्यम से पाइप। dd का डिफ़ॉल्ट इनपुट स्टडिन है और डिफ़ॉल्ट आउटपुट stdout है; जब यह stdin / stdout I / O समाप्त करता है, तो यह stderr को रिपोर्ट करेगा कि उसने कितना डेटा स्थानांतरित किया है।

यदि आप dd के आउटपुट को कैप्चर करना चाहते हैं और अन्य प्रोग्राम पहले से ही stderr पर बात करते हैं, तो दूसरे फाइल-डिस्क्रिप्टर का उपयोग करें। उदाहरण के लिए,

$ exec 4>~/fred
$ input-command | dd 2>&4 | output-command
$ exec 4>&-

2
क्या आप execफ़ाइल को सीधे सीधे आउटपुट में नहीं छोड़ सकते हैं? input-command | dd 2>~/fred | output-command
अगली सूचना तक रोक दिया गया।

2
उह, हाँ। मैं स्पष्ट रूप से "उन" क्षणों में से एक था, क्षमा करें।
फिल पी

28

उपयोग पीवी पाइप दर्शक। यह एक महान उपकरण है। एक बार जब आप इसके बारे में जान लेंगे तो आप कभी नहीं जान पाएंगे कि आप इसके बिना कैसे रहे।

यह आपको एक प्रगति बार, और स्थानांतरण की 'गति' भी दिखा सकता है।


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

उपयोग का उदाहरण: cat file | pv -bफ़ाइल का आकार लौटाएगा।
छड़गोरास

6

process_a | tee >(process_b) | wc --bytesशायद काम कर जाये। फिर आप wcजहाँ-जहाँ आपको इसकी आवश्यकता है, उसकी गणना कर सकते हैं । यदि आपको process_bकुछ भी stdout/ के लिए आउटपुट देता है, stderrतो आपको शायद इसे कहीं और अनुप्रेषित करने की आवश्यकता होगी, यदि केवल /dev/null

थोड़े विपरीत उदाहरण के लिए:

filestore:~# cat document.odt | tee >(dd of=/dev/null 2>/dev/null) | wc --bytes
4295

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


मैं इस समाधान को पसंद करता हूं, दुख की बात है कि मैं जिस शेल का उपयोग कर रहा हूं (व्यस्त बॉक्स)> () संकेतन का समर्थन नहीं करता है, लेकिन यह ऐसा करने का एक तरीका प्रदान करता है जो मैं उसके बाद कर रहा हूं।
साइमन हॉजसन

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

1

मुझे पता है कि मुझे पार्टी में देर हो रही है, लेकिन मेरा मानना ​​है कि मेरे पास एक अच्छा जवाब है जो इस उपयोगी सूत्र को बढ़ा सकता है।
यह @Phil P और @David Spillett उत्तर का मिश्रण है, लेकिन:

  • @ पील पी के अलग से, यह एक नई फ़ाइल बनाने से बचता है
  • @ डेविड स्पिललेट के अलग से, यह पाइपलाइन संरचना को बनाए रखता है

प्रक्रिया-बी के किसी भी आउटपुट के साथ बाइट्स-काउंट को stdout में प्रिंट किया जाता है।
आउटपुट ( Bytes:उदाहरण में) के साथ काम करते समय बाइट्स वाली रेखा को पहचानने के लिए आप उपसर्ग का उपयोग कर सकते हैं ।

exec 3>&1
process_a | tee >({ echo -n 'Bytes:'; wc -c; } >&3) | process_b
exec 3>&-

चेतावनी:
आउटपुट में लाइनों के क्रम पर भरोसा न करें
। आदेश अप्रत्याशित है और समान मापदंडों के साथ एक ही स्क्रिप्ट को कॉल करते समय भी यह हमेशा अलग हो सकता है!


अफसोस की बात है, यह अभी भी एक बैश-केवल निर्माण है ...
मिखाइल टी।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.