पाइप को कैसे समझें


21

जब मैंने बस बैश में पाइप का इस्तेमाल किया, तो मैंने इस बारे में ज्यादा नहीं सोचा। लेकिन जब मैंने सिस्टम कॉल पाइप () फोर्क () के साथ मिलकर सी कोड उदाहरण का उपयोग किया, तो मुझे आश्चर्य हुआ कि पाइप कैसे समझें, जिसमें अनाम पाइप और नामित पाइप दोनों शामिल हैं।

अक्सर यह सुना जाता है कि "लिनक्स / यूनिक्स में सब कुछ एक फाइल है"। मुझे आश्चर्य है कि क्या एक पाइप वास्तव में एक फाइल है ताकि एक हिस्सा इसे पाइप फ़ाइल से लिखता है, और दूसरा हिस्सा पाइप फ़ाइल से पढ़ता है? यदि हाँ, तो अनाम पाइप के लिए पाइप फ़ाइल कहाँ बनाई गई है? में / tmp, / dev, या ...?

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

जवाबों:


23

आपके प्रदर्शन प्रश्न के बारे में, पाइप फ़ाइलों की तुलना में अधिक कुशल हैं क्योंकि किसी भी डिस्क IO की आवश्यकता नहीं है। तो cmd1 | cmd2अधिक कुशल से अधिक है cmd1 > tmpfile; cmd2 < tmpfile(यह सच नहीं हो सकता है अगर tmpfileरैम डिस्क या अन्य मेमोरी डिवाइस पर नामित पाइप के रूप में समर्थित है, लेकिन अगर यह एक नामित पाइप है, तो इसे cmd1पृष्ठभूमि में चलाया जाना चाहिए क्योंकि पाइप पूर्ण हो जाने पर इसका आउटपुट ब्लॉक हो सकता है )। आप का परिणाम की जरूरत है cmd1और अभी भी करने के लिए इसके उत्पादन भेजने की जरूरत है cmd2, तो आप चाहिए cmd1 | tee tmpfile | cmd2की अनुमति देगा जो cmd1और cmd2परहेज डिस्क से संचालन को पढ़ने के समानांतर में चलाने के लिए cmd2

यदि एक ही पाइप से कई प्रक्रियाएं पढ़ी / लिखी जाती हैं तो नामांकित पाइप उपयोगी होते हैं। वे तब भी उपयोगी हो सकते हैं जब फ़ाइलों का उपयोग करने की आवश्यकता वाले अपने IO के लिए stdin / stdout का उपयोग करने के लिए कोई प्रोग्राम डिज़ाइन नहीं किया गया हो । मैंने इटैलिक में फाइलें डाल दीं क्योंकि नामित पाइप बिल्कुल स्टोरेज पॉइंट की फाइलें नहीं हैं क्योंकि वे मेमोरी में रहते हैं और एक निश्चित बफर साइज है, भले ही उनके पास फाइलसिस्टम एंट्री हो (संदर्भ उद्देश्य के लिए)। अन्य बातों के बस के बारे में सोच: यूनिक्स में फाइल किया जा रहा बिना फाइल सिस्टम प्रविष्टियाँ /dev/nullया में अन्य लोगों प्रविष्टियों /devया /proc

जैसा कि पाइप (नाम और अनाम) में एक निश्चित बफर आकार है, उन्हें पढ़ने / लिखने के संचालन ब्लॉक कर सकते हैं, जिससे IOWait राज्य में पढ़ने / लिखने की प्रक्रिया चल सकती है। इसके अलावा, मेमोरी बफर से पढ़ते समय आपको ईओएफ कब मिलता है? इस व्यवहार पर नियम अच्छी तरह से परिभाषित हैं और आदमी में पाए जा सकते हैं।

एक चीज जिसे आप पाइप के साथ नहीं कर सकते हैं (नाम और अनाम) डेटा में वापस मांगता है। जैसा कि उन्हें मेमोरी बफर का उपयोग करके कार्यान्वित किया जाता है, यह समझ में आता है।

के बारे में "everything in Linux/Unix is a file", मैं सहमत नहीं हूं। नामित पाइप में फ़ाइल सिस्टम प्रविष्टियाँ हैं, लेकिन वास्तव में फ़ाइल नहीं हैं। फ़ाइल सिस्टम प्रविष्टियाँ नहीं हैं (शायद को छोड़कर /proc)। हालाँकि, UNIX पर अधिकांश IO परिचालनों को रीड / राइट फंक्शन का उपयोग करके किया जाता है , जिसमें एक फाइल डिस्क्रिप्टर की जरूरत होती है , जिसमें अनाम पाइप (सॉकेट) शामिल है। मुझे नहीं लगता कि हम ऐसा कह सकते हैं "everything in Linux/Unix is a file", लेकिन हम निश्चित रूप से ऐसा कह सकते हैं "most IO in Linux/Unix is done using a file descriptor"


धन्यवाद! क्या दो कमांड समानांतर में चलने वाले पाइप से जुड़े होते हैं, दूसरे के बजाय पहले खत्म होने के बाद चलने लगते हैं?
टिम

हाँ, 2 कमांड समानांतर में चलाए जाते हैं। यदि वे बफर से अधिक 1 आउटपुट और नहीं थे, तो इसे अवरुद्ध कर दिया जाएगा। आप इसे चलाकर cmd1 > fifoऔर cmd2 < fifo2 अलग-अलग गोले में नामांकित पाइप के साथ बनाकर देख सकते हैं mkfifo fifo
jfg956

एक और परीक्षण जो आप कर सकते हैं, cmd2जबकि cmd1अभी भी चल रहा है , को मारना है: cmd1शायद एक टूटे हुए पाइप मेसेज को रिपोर्ट करना बंद कर देगा।
jfg956

धन्यवाद! आपका क्या मतलब है अवरुद्ध हो जाएगा? यदि ऐसा होता है, तो क्या इसका मतलब है कि ब्लॉक के बाद स्ट्रीम में तारीख खो जाएगी?
टिम

2
डेटा गुम नहीं हुआ है। यदि पाइप बफर भरा हुआ है, cmd1तो पाइप को लिखें तभी वापस आएगा जब cmd2पाइप से डेटा पढ़ा होगा। उसी तरह, cmd2एक पाइप से पढ़ा गया ब्लॉक अवरुद्ध हो जाएगा अगर बफर cmd1पाइप तक लिखता है।
jfg956

4

UNIX दर्शन के मूल बुनियादी सिद्धांतों में से दो हैं

  1. छोटे प्रोग्राम बनाने के लिए जो एक काम को अच्छी तरह से करते हैं।
  2. और उम्मीद है कि हर प्रोग्राम का आउटपुट दूसरे के लिए इनपुट बन जाएगा, जैसा कि
    अभी तक अज्ञात है, प्रोग्राम है।

    पाइपों का उपयोग आपको
    अपने वांछित परिणाम प्राप्त करने के लिए आदेशों की अत्यंत शक्तिशाली श्रृंखला बनाने के लिए इन दो डिज़ाइन बुनियादी बातों के प्रभावों का लाभ उठाने देता है।

    फ़ाइलों पर काम करने वाले अधिकांश कमांड-लाइन प्रोग्राम भी इनपुट में मानक (कीबोर्ड के माध्यम से इनपुट) और आउटपुट को मानक आउट (
    स्क्रीन पर प्रिंट) में स्वीकार कर सकते हैं ।

    कुछ कमांड केवल एक पाइप के भीतर संचालित करने के लिए डिज़ाइन किए गए हैं जो फाइलों पर सीधे काम नहीं कर सकते हैं।

    उदाहरण के लिए trकमांड

  ls -C | tr 'a-z' 'A-Z'
    cmd1 | cmd2
  • Cmd1 के STDOUT को स्क्रीन के बजाय cmd2 के STDIN में भेजता है।

  • STDERR को पाइप के पार नहीं भेजा जाता है।

    संक्षेप में Pipes is character (|)कमांड कनेक्ट कर सकते हैं।

    कोई भी कमांड जो STDOUT को लिखती है, उसका उपयोग पाइप के बायीं ओर किया जा सकता है।

       ls - /etc | less 

    एसटीडीआईएन से जो भी कमांड पढ़ता है, उसका उपयोग पाइप के दाईं ओर किया जा सकता है।

       echo "test print" | lpr 

    एक पारंपरिक पाइप "अनाम" है क्योंकि यह गुमनाम रूप से मौजूद है और जब तक प्रक्रिया चल रही है, तब तक बनी रहती है। एक नामित पाइप सिस्टम-स्थायी है और यह प्रक्रिया के जीवन से परे मौजूद है और इसे हटा दिया जाना चाहिए, क्योंकि यह अब उपयोग नहीं किया जा रहा है। अंतर-प्रक्रिया संचार (IPC) करने के लिए प्रक्रियाएं आमतौर पर नामित पाइप (आमतौर पर एक फ़ाइल के रूप में दिखाई देने वाली) से जुड़ी होती हैं।

स्रोत: http://en.wikipedia.org/wiki/Named_pipe


3

अन्य उत्तरों के पूरक के लिए ...

stdin और stdout फाइल डिस्क्रिप्टर होते हैं और पढ़े जाते हैं और लिखे जाते हैं जैसे कि वे फाइल हैं। इसलिए आप कर सकते हैं echo hi | grep hi, और यह एक पाइप के साथ प्रतिध्वनि की जगह लेगा और इस पाइप के दूसरे छोर पर grep के स्टड की जगह लेगा।


1

सब कुछ एक फाइल है।

यदि हम वाक्यांश को भी शाब्दिक रूप से लेते हैं, तो हम "हमारे पास केवल फाइलें हैं, और कुछ नहीं" के अर्थ के साथ समाप्त होगा। यह सही व्याख्या नहीं है, तो क्या है।

जब हम कहते हैं कि "सब कुछ एक फ़ाइल है", हम यह नहीं कह रहे हैं कि सब कुछ एक डिस्क पर संग्रहीत है। हम कह रहे हैं कि सब कुछ एक फाइल की तरह दिखता है, पढ़ा जा सकता है, लिखा जा सकता है।

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

हर चीज का एक नाम है (कुछ प्रणालियों पर: उदाहरण के लिए डेबियन ग्नू / लिनक्स, और कई अन्य ग्नू / लिनक्स)।

  • सभी खुली फ़ाइलों को एक फ़ाइल नाम मिलता है। देख/proc/self/fd/…
  • नेटवर्क सॉकेट एक फ़ाइल नाम /dev/tcp
    उदाहरण के साथ खोला जा सकता हैcat </dev/tcp/towel.blinkenlights.nl/23

वह अंतिम भाग केवल एक /procफाइल सिस्टम के साथ सिस्टम पर मान्य है , और सिस्टम पर (या गोले) जो एक /dev/tcpफ़ाइल संरचना प्रदान करता है।
Kusalananda
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.