2009-07-02 19 views
29

पाइपिंग कैसे काम करता है? यदि मैं सीएलआई के माध्यम से एक प्रोग्राम चलाता हूं और आउटपुट को एक फ़ाइल में रीडायरेक्ट करता हूं तो क्या मैं उस फ़ाइल को किसी अन्य प्रोग्राम में पाइप कर सकता हूं जैसा लिखा जा रहा है?लिनक्स में पाइप कैसे काम करता है?

असल में जब फ़ाइल में एक पंक्ति लिखी जाती है तो मैं इसे अपने दूसरे एप्लिकेशन में तुरंत पाइप करना चाहता हूं (मैं गतिशील रूप से किसी मौजूदा प्रोग्राम से ग्राफ को खींचने की कोशिश कर रहा हूं)। बस अगली कमांड पर जाने से पहले पाइपिंग पहले कमांड को पूरा करता है तो बस अनिश्चित।

किसी भी फ़ीड वापस की सराहना की जाएगी!

+0

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

+0

विंडोज़ में पिपिंग लिनक्स से अलग है ... मेरा मानना ​​है कि लिनक्स कुछ प्रकार के रिंग-बफर का उपयोग करता है और अच्छी तरह से प्रदर्शन करने के लिए समवर्ती प्रोग्रामिंग सिद्धांत (निर्माता-उपभोक्ता समस्या इत्यादि) का उपयोग करता है। मुझे लगता है कि विंडोज़ तब तक इंतजार कर रहा है जब तक कि दूसरा प्रोग्राम कॉल करने से पहले किया जाता है। –

उत्तर

54

यदि आप किसी अन्य के इनपुट में एक कार्यक्रम का उत्पादन रीडायरेक्ट करने के लिए चाहते हैं, बस एक साधारण पाइप लाइन का उपयोग करें:

program1 arg arg | program2 arg arg 

आप एक फ़ाइल और पाइप इसे में program1 के उत्पादन में सहेजना चाहते हैं program2 में, आप tee(1) उपयोग कर सकते हैं:

program1 arg arg | tee output-file | program2 arg arg 

एक पाइप लाइन में सभी कार्यक्रमों को एक साथ चलाए जा रहे हैं। अधिकांश कार्यक्रम आमतौर पर I/O अवरुद्ध करते हैं: यदि वे अपने इनपुट को पढ़ने का प्रयास करते हैं और कुछ भी नहीं है, तो वे ब्लॉक: यानी, वे रुकते हैं, और ऑपरेटिंग सिस्टम उन्हें तब तक चलाने के लिए शेड्यूल करता है जब तक कि अधिक इनपुट उपलब्ध न हो जाए (सीपीयू खाने से बचने के लिए)। इसी प्रकार, यदि पाइपलाइन में पहले एक प्रोग्राम बाद में प्रोग्राम लिखने से पहले तेज़ी से लिख रहा है, तो अंततः पाइप का बफर भर जाता है और लेखक ब्लॉक करता है: ओएस इसे तब तक शेड्यूल करता है जब तक कि पाइप के बफर को पाठक द्वारा खाली नहीं किया जाता है, और फिर यह फिर से लिखना जारी रख सकता है।


संपादित

आप program1 कमांड लाइन पैरामीटर के रूप में के उत्पादन में उपयोग करना चाहते हैं, तो आप backquotes या $() सिंटैक्स का उपयोग कर सकते हैं:

# Runs "program1 arg", and uses the output as the command-line arguments for 
# program2 
program2 `program1 arg` 

# Same as above 
program2 $(program1 arg) 

$() वाक्य रचना पसंद किया जाना चाहिए, क्योंकि वे स्पष्ट हैं, और वे घोंसला जा सकते हैं।

+0

किसी कारण से प्रारंभिक कार्यक्रम (इस मामले में प्रोग्राम 1) पाइपिंग के साथ सहयोग नहीं करता है। क्या इसके अंदर कोई विशेष कोड आवश्यक है? मैंने आपके द्वारा रखी गई सरल पाइप करने की कोशिश की और 1) प्रोग्राम 1 के लिए सीएलआई इंटरफ़ेस शुरू नहीं हुआ, और 2) प्रोग्राम 2 पैरामीटर के लिए पूछा गया (हालांकि मैं 2 के पैरामीटर के रूप में 1 के आउटपुट को पास करने का प्रयास कर रहा हूं) –

+0

@ जोन , ऐसा लगता है कि प्रोग्राम 1 stdout या प्रोग्राम 2 पर अपना आउटपुट नहीं भेज रहा है stdin से नहीं पढ़ रहा है। आप कौन से प्रोग्राम चलाने की कोशिश कर रहे हैं? –

+0

एक ध्वज है कि कुछ प्रोग्राम यह पता लगाने के लिए पढ़ सकते हैं कि वे पाइप में हैं या नहीं ... 'ls' यह तय करने के लिए करता है कि फाइल जानकारी कैसे प्रदर्शित करें (जब पाइप में, तो प्रत्येक फ़ाइल की एक पंक्ति पर इसका अपना आदि) –

9

अपने कार्यक्रमों stdin और stdout का उपयोग कर संवाद कर रहे हैं, तो आप लिखने के बाद लगता है कि आप या तो बुला रहे हैं fflush(stdout) कर सकते हैं या निष्क्रिय करने के लिए मानक आईओ बफरिंग किसी तरह लगता है। सबसे अच्छा संदर्भ जो मैं सोच सकता हूं कि वास्तव में वर्णन करता है कि सी/सी ++ में पाइपलाइनों को सर्वोत्तम रूप से कैसे कार्यान्वित किया जाए Advanced Programming in the UNIX Environment या UNIX Network Programming: Volume 2 है। आप शायद this article से भी शुरू कर सकते हैं।

25

पाइपिंग दूसरे चलाने से पहले पहला आदेश पूरा नहीं करता है। यूनिक्स (और लिनक्स) पाइपिंग सभी आदेशों को एक साथ चलाता है।

  • यह इनपुट के लिए भूखा है यदि एक आदेश निलंबित कर दिया जाएगा।

  • इसने अपने उत्तराधिकारी का उपभोग करने के लिए तैयार होने से काफी अधिक उत्पादन किया है।

ज्यादातर कार्यक्रमों के लिए उत्पादन बफ़र, जिसका अर्थ है ओएस पाइप लाइन के अगले चरण के लिए उस पर पार करने से पहले उत्पादन (शायद 8000 अक्षर या तो) की एक पर्याप्त राशि जमा कि है। प्रक्रियाओं और कर्नेल के बीच आगे और पीछे स्विचिंग से बचने के लिए यह बफरिंग का उपयोग किया जाता है।

आप एक पाइप लाइन पर उत्पादन चाहते हैं तुरंत भेजा जाना है, तो आप उपयोग कर सकते हैं unbuffered मैं/हे, जो सी में fflush() की तरह कुछ बुला सुनिश्चित करें कि किसी भी बफ़र उत्पादन तुरंत करने पर भेजा है होने का क्या मतलब अगली प्रक्रिया। Unbuffered इनपुट भी संभव है लेकिन आम तौर पर अनावश्यक है क्योंकि इनपुट के लिए भूखा एक प्रक्रिया आमतौर पर एक पूर्ण बफर की प्रतीक्षा नहीं करता है, लेकिन आप जो भी इनपुट प्राप्त कर सकते हैं उसे संसाधित करेंगे।

विशिष्ट अनुप्रयोगों के लिए unbuffered आउटपुट की अनुशंसा नहीं की जाती है; आप आमतौर पर डिफ़ॉल्ट के साथ सबसे अच्छा प्रदर्शन मिलता है। हालांकि, आपके मामले में, जहां आप गतिशील ग्राफिंग करना चाहते हैं तुरंत पहली प्रक्रिया में जानकारी उपलब्ध है, तो आप निश्चित रूप से unbuffered आउटपुट का उपयोग करना चाहते हैं। यदि आप सी का उपयोग कर रहे हैं, तो fflush(stdout) पर कॉल करना जब भी आप आउटपुट भेजना चाहते हैं तो पर्याप्त होगा।

3

यदि आपके दो प्रोग्राम फाइलों को पढ़ने और लिखने पर जोर देते हैं और stdin/stdout का उपयोग नहीं करते हैं, तो आप पाएंगे कि आप फ़ाइल के बजाय नामित पाइप का उपयोग कर सकते हैं।

$ mknod /tmp/named-pipe p 

फिर अपने कार्यक्रमों पढ़ सकते हैं और/tmp/नामित-पाइप (जो भी पथ/नाम यदि आपको लगता है उचित है उपयोग) करने के लिए लिखने के लिए कॉन्फ़िगर करें:

mknod (1) कमांड के साथ एक नामित पाइप बनाएँ।

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

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