2016-01-31 8 views
16

के साथ काम नहीं कर रहा है जब मैं निम्नलिखित Bash स्क्रिप्ट चलाता हूं, तो मैं इसे Hello प्रिंट करने की अपेक्षा करता हूं। इसके बजाए, यह एक खाली रेखा प्रिंट करता है और बाहर निकलता है।पाइपिंग echo कमांड

echo 'Hello' | echo 

क्यों नहीं piping उत्पादन echo से काम echo के लिए करता है?

+2

आपको लगता है कि 'बिल्ली' की तरह व्यवहार करने के लिए दूसरी 'गूंज' की अपेक्षा की जा रही है। –

उत्तर

25

echo अपने सभी तर्कों को प्रिंट करता है। यह stdin से नहीं पढ़ता है। तो stdin पर Hello को अनदेखा करते हुए, इसके सभी तर्क (कोई नहीं) और बाहर निकलता है।

एक प्रोग्राम है जो अपने stdin और प्रिंट पढ़ता है कि stdout करने के लिए, का उपयोग cat के लिए:

$ echo Hello | cat 
Hello 
+1

या '$ echo हैलो | xargs echo' जो 'echo हैलो | के बराबर है डिफ़ॉल्ट रूप से xargs'। – daGo

2

यह इसलिए क्योंकि echo (दोनों अंतर्निहित और /bin/echo) stdin से कुछ भी पढ़ा नहीं है।

उपयोग cat बजाय:

echo 'Hello' | cat 
Hello 

या बिना पाइप:

cat <<< 'Hello' 
3

पाइपिंग stdin से आदानों लेने आदेश के लिए ही किया जा सकता है। लेकिन echo stdin से नहीं लेता है। यह तर्क से इनपुट लेगा और इसे प्रिंट करेगा। तो यह काम नहीं करेगा। गूंजने के लिए आप echo $(echo 'hello')

8

जैसे कुछ कर सकते हैं आपको पाइप समझने की प्रतीत नहीं होती है। इस मामले में वे अज्ञात पाइप के रूप में अधिक सटीक रूप से जाने जाते हैं, क्योंकि उनके पास कोई नाम नहीं है (नामित पाइप भी हैं)। बेनामी पाइप केवल संबंधित प्रक्रियाओं के बीच काम करते हैं, उदाहरण के लिए एक ही माता-पिता के साथ प्रक्रियाएं।

पाइप्स सी रनटाइम-लाइब्रेरी के परिणामस्वरूप आईओ सिस्टम का हिस्सा हैं। ये स्ट्रीम डिफ़ॉल्ट रूप से buffered (एक अपवाद है) हैं। असल में एक पाइप आउटपुट बफर को एक प्रक्रिया से दूसरे के इनपुट बफर में जोड़ रहा है।

पहले तीन धाराओं का इस्तेमाल किया (बुलाया फ़ाइल वर्णनकर्ता) 0 गिने जा रहे हैं, 1, और 2 पहले, 0, मानक इनपुट, या stdin (नाम सी में प्रयुक्त) के रूप में जाना जाता है। डिफ़ॉल्ट रूप से यह कीबोर्ड से जुड़ा हुआ है, लेकिन इसे < प्रतीक या पाइप के दाईं ओर प्रोग्राम नाम का उपयोग करके रीडायरेक्ट किया जा सकता है।

दूसरा, 1, मानक आउटपुट, या stdout के रूप में जाना जाता है। डिफ़ॉल्ट रूप से यह टर्मिनल स्क्रीन से जुड़ा हुआ है, लेकिन > प्रतीक या पाइप के बाईं ओर प्रोग्राम नाम का उपयोग कर रीडायरेक्ट किया जा सकता है।

तो:

echo 'Hello' | echo 

echo से मानक उत्पादन लेता है और echo के मानक इनपुट को पास कर देता। लेकिन echo stdin नहीं पढ़ता है! तो कुछ भी नहीं होता है।

फ़िल्टर प्रोग्राम कमांड लाइन पर निर्दिष्ट फ़ाइल नामों को संसाधित करें। अगर कोई फ़ाइल नाम नहीं दिया जाता है तो वे stdin पढ़ते हैं। उदाहरणों में cat, grep, और sed शामिल हैं, लेकिन echo शामिल नहीं हैं। उदाहरण के लिए:

echo 'Hello' | cat 

प्रदर्शित करेगा 'नमस्ते', और cat बेकार है (यह अक्सर होता है)।

echo 'Hello' | cat file1 

echo से उत्पादन पर ध्यान नहीं देगा और बस file1 की सामग्री को प्रदर्शित करते हैं। याद रखें कि stdin केवल तभी पढ़ा जाता है जब कोई फ़ाइल नाम नहीं दिया जाता है।

आपको यह प्रदर्शित करने के लिए क्या लगता है?

echo 'Hello' | cat < file1 file2 

और क्यों?

अंत में, तीसरी धारा, 2, मानक त्रुटि कहा जाता है, या stderr, और यह एक unbuffered है। इसे पाइपों द्वारा अनदेखा किया जाता है, क्योंकि वे केवल स्टडीन और स्टडआउट के बीच काम करते हैं। हालांकि, अगर आप stdout उपयोग करने के लिए stderr अनुप्रेषित कर सकते हैं (man dup2 देखें):

myprog 2>&1 | anotherprog 

2>&1 का अर्थ है "छी वर्णनकर्ता 1 के रूप में ही जगह पर फ़ाइल वर्णनकर्ता 2 redirect"।

उपर्युक्त सामान्य व्यवहार है, हालांकि एक कार्यक्रम यह सब कुछ ओवरराइड कर सकता है यदि वह चाहता है। यह फ़ाइल वर्णनकर्ता 2 से पढ़ा जा सकता है, उदाहरण के लिए। मैंने प्रक्रिया प्रतिस्थापन और दस्तावेजों जैसे पुनर्निर्देशन के अन्य रूपों सहित कई अन्य विवरणों को छोड़ दिया है।

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