बैश पाइप हैंडलिंग


29

क्या किसी को पता है कि कैसे पाश पाइप के माध्यम से डेटा भेजता है?

cat file.txt | tail -20 

क्या यह आदेश फ़ाइल.txt की सभी सामग्री को एक बफर में प्रिंट करता है, जिसे तब पूंछ द्वारा पढ़ा जाता है? या यह आदेश करता है, कहें, लाइन.txt लाइन की सामग्री को लाइन से प्रिंट करें, और उसके बाद पूंछ को संसाधित करने के लिए प्रत्येक पंक्ति पर रोकें, और फिर अधिक डेटा मांगें?

कारण मैं पूछता हूं कि मैं एक एम्बेडेड डिवाइस पर एक प्रोग्राम लिख रहा हूं जो मूल रूप से डेटा के कुछ हिस्सों पर संचालन का अनुक्रम करता है, जहां एक ऑपरेशन का आउटपुट अगले ऑपरेशन के इनपुट के रूप में भेज दिया जाता है। मैं जानना चाहता हूं कि लिनक्स (बाश) इसे कैसे संभालता है, इसलिए कृपया मुझे एक सामान्य उत्तर दें, विशेष रूप से तब नहीं होता जब मैं "cat file.txt | tail -20" चलाता हूं।

आपके प्रतिक्रियाओं के लिए अग्रिम धन्यवाद!

संपादित करें: शोग 9 ने एक प्रासंगिक विकिपीडिया अनुच्छेद की ओर इशारा किया, इससे मुझे सीधे लेख में नहीं पहुंचा, लेकिन इससे मुझे यह खोजने में मदद मिली: http://en.wikipedia.org/wiki/Pipeline_%28Unix%29#Implementation जिसमें मेरी जानकारी थी जो मैं ढूंढ रहा था।


मुझे खुद को स्पष्ट नहीं करने के लिए खेद है। बेशक आप एक पाइप का उपयोग कर रहे हैं और निश्चित रूप से आप कमांड के संबंधित हिस्सों के stdin और stdout का उपयोग कर रहे हैं। मैंने माना था कि राज्य के लिए बहुत स्पष्ट था।

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

54

मैंने थोड़ा और विस्तृत स्पष्टीकरण लिखने का फैसला किया।

यहां "जादू" ऑपरेटिंग सिस्टम में निहित है। दोनों कार्यक्रम लगभग एक ही समय में शुरू होते हैं, और एक ही समय में चलते हैं (ऑपरेटिंग सिस्टम उन्हें प्रोसेसर पर चलाने के समय के स्लाइस निर्दिष्ट करता है) क्योंकि आपके कंप्यूटर पर हर दूसरे एक साथ चलने की प्रक्रिया (टर्मिनल एप्लिकेशन और कर्नेल समेत) । इसलिए, किसी भी डेटा को पारित करने से पहले, प्रक्रियाएं जो भी प्रारंभिक आवश्यक हो रही हैं। आपके उदाहरण में, पूंछ '-20' तर्क को पार्स कर रहा है और बिल्ली 'file.txt' तर्क को पार्स कर रही है और फ़ाइल खोल रही है। किसी बिंदु पर पूंछ उस बिंदु तक पहुंच जाएगी जहां उसे इनपुट की आवश्यकता होगी और यह ऑपरेटिंग सिस्टम को बताएगा कि यह इनपुट की प्रतीक्षा कर रहा है। किसी अन्य बिंदु पर (या तो पहले या बाद में, इससे कोई फर्क नहीं पड़ता) बिल्ली stdout का उपयोग कर ऑपरेटिंग सिस्टम में डेटा पास करना शुरू कर देगी। यह ऑपरेटिंग सिस्टम में एक बफर में चला जाता है। बिल्ली द्वारा बफर में कुछ डेटा डालने के बाद अगली बार पूंछ प्रोसेसर पर एक समय टुकड़ा हो जाता है, यह उस डेटा (या यह सब कुछ) को पुनर्प्राप्त करेगा जो ऑपरेटिंग सिस्टम पर बफर छोड़ देता है। जब बफर खाली होता है, तो किसी बिंदु पर पूंछ को अधिक डेटा आउटपुट करने के लिए बिल्ली की प्रतीक्षा करनी होगी। यदि बिल्ली पूंछ की तुलना में डेटा को बहुत तेजी से आउटपुट कर रही है तो इसे संभाला जा रहा है, बफर का विस्तार होगा।बिल्ली अंततः डेटा आउटपुट कर दी जाएगी, लेकिन पूंछ अभी भी प्रसंस्करण होगी, इसलिए बिल्ली बंद हो जाएगी और पूंछ बफर में सभी शेष डेटा को संसाधित करेगा। ऑपरेटिंग सिस्टम पूंछ को संकेत देगा जब उनका ईओएफ के साथ कोई और आने वाला डेटा नहीं है। पूंछ शेष डेटा को संसाधित करेगा। इस मामले में, पूंछ शायद 20 लाइनों के गोलाकार बफर में सभी डेटा प्राप्त कर रहा है, और जब इसे ऑपरेटिंग सिस्टम द्वारा संकेत दिया जाता है कि कोई और आने वाला डेटा नहीं है, तो यह आखिरी बीस लाइनों को अपने स्वयं के स्टडआउट पर डंप करता है, जो कि बस टर्मिनल में प्रदर्शित हो जाता है। चूंकि पूंछ बिल्ली की तुलना में एक बहुत ही सरल कार्यक्रम है, इसलिए संभवतः बिल्ली को डेटा को बफर में रखने की प्रतीक्षा करने में अधिकतर समय व्यतीत होगा।

एकाधिक प्रोसेसर वाले सिस्टम पर, दोनों प्रोग्राम एक ही प्रोसेसर कोर पर वैकल्पिक समय स्लाइस साझा नहीं करेंगे, बल्कि अलग-अलग कोर पर एक ही समय में चल रहे हैं।

थोड़ा और विस्तार प्राप्त करने के लिए, यदि आप लिनक्स में 'टॉप' जैसे किसी प्रकार की प्रक्रिया मॉनीटर (ऑपरेटिंग सिस्टम विशिष्ट) खोलते हैं तो आपको चल रही प्रक्रियाओं की पूरी सूची दिखाई देगी, जिनमें से अधिकांश प्रभावी रूप से 0% का उपयोग कर रहे हैं प्रोसेसर अधिकतर एप्लिकेशन, जब तक कि वे डेटा क्रंच नहीं कर लेते हैं, अपना अधिकांश समय कुछ भी नहीं करते हैं। यह अच्छा है, क्योंकि यह अन्य प्रक्रियाओं को प्रोसेसर को उनकी आवश्यकताओं के अनुसार अनजान पहुंच की अनुमति देता है। यह मूल रूप से तीन तरीकों से पूरा किया जाता है। एक प्रक्रिया नींद (एन) शैली निर्देश प्राप्त कर सकती है जहां यह मूल रूप से कर्नेल को एन मिलीसेकंड का इंतजार करने के लिए कहता है ताकि इसे काम करने के लिए एक और बार टुकड़ा दिया जा सके। आमतौर पर किसी प्रोग्राम को किसी अन्य प्रोग्राम से कुछ की प्रतीक्षा करने की आवश्यकता होती है, जैसे 'पूंछ' बफर में प्रवेश करने के लिए अधिक डेटा की प्रतीक्षा कर रहा है। इस मामले में अधिक डेटा उपलब्ध होने पर ऑपरेटिंग सिस्टम प्रक्रिया को जगाएगा। अंत में, कर्नेल निष्पादन के बीच में एक प्रक्रिया को पूर्ववत कर सकता है, कुछ प्रोसेसर समय स्लाइस को अन्य प्रक्रियाओं में दे सकता है। 'बिल्ली' और 'पूंछ' सरल कार्यक्रम हैं। इस उदाहरण में, पूंछ बफर पर अधिक डेटा के लिए इंतजार कर रहा है, और बिल्ली ऑपरेटिंग सिस्टम को हार्डड्राइव से डेटा पुनर्प्राप्त करने के लिए इंतजार कर रही है। बाधा भौतिक माध्यम की गति (या धीमा) है कि फ़ाइल को संग्रहीत किया जाता है। जब आप इस आदेश को पहली बार चलाते हैं तो उस अवधारणात्मक देरी का पता लग सकता है कि डिस्क ड्राइव पर पढ़ने वाले सिर के लिए हार्डड्राइव पर स्थिति की तलाश करने के लिए समय लगता है, जहां 'file.txt' है। यदि आप दूसरी बार कमांड चलाते हैं, तो ऑपरेटिंग सिस्टम में स्मृति में कैश किए गए file.txt की सामग्री होगी, और आपको किसी भी अवधारणात्मक देरी दिखाई नहीं देगी (जब तक कि file.txt बहुत बड़ा न हो, या फ़ाइल अब कैश नहीं की जाती है ।)

अधिकांश आपरेशन आप अपने कंप्यूटर पर कर आईओ बाध्य है, जो कि आप आमतौर पर डेटा आपकी हार्डड्राइव से, या नेटवर्क डिवाइस से आने के लिए इंतजार कर रहे हैं कहने के लिए है, आदि कर रहे हैं


0

बिल्ली डेटा को मानक आउट करने के लिए प्रिंट करेगा, जो पूंछ के मानक में रीडायरेक्ट किया जाता है। यह बैश के मैन पेज में देखा जा सकता है।

दूसरे शब्दों में, कोई रोका नहीं जा रहा है, पूंछ मानक में पढ़ रहा है और बिल्ली सिर्फ मानक आउट करने के लिए लिख रही है।


1

शोग 9 पहले ही विकिपीडिया लेख का संदर्भ देता है, लेकिन implementation section में आपके इच्छित विवरण हैं। मूल कार्यान्वयन एक बाध्य बफर है।