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


23

मैं बस टर्मिनल में कुछ कमांड चला रहा था और मुझे आश्चर्य होने लगा था, क्या पाइप के कमांड को चलाने पर यूनिक्स / लिनक्स शॉर्टकट ले लेता है?

उदाहरण के लिए, मान लें कि मेरे पास एक मिलियन लाइनें हैं, जिनमें से पहले 10 में एक फाइल है hello world। यदि आप कमांड चलाते हैं तो 10 कमांड grep "hello world" file | headमिलते ही पहला कमांड बंद हो जाता है, या यह पूरी फाइल को पहले सर्च करना जारी रखता है?


2
इसलिए ग्नू ग्रीप का -mतर्क है।
पॉल टॉम्बलिन

3
टर्मिनल का इससे कोई लेना-देना नहीं है। पाइप कमांड को शेल द्वारा प्रबंधित किया जाता है।
कीथ थॉम्पसन

@KeithThompson मेरी अज्ञानता को क्षमा करें, मैं शब्दावली पर बड़ा नहीं हूं, यह निश्चित नहीं था कि इसे टर्मिनल, शेल या कमांड लाइन कहा जाए। मेरे प्रश्न का संपादन करने के लिए स्वतंत्र महसूस करें :)
led डिसएगंटेडडब्लूट

जवाबों:


30

की तरह। शेल को पता नहीं है कि आप जो कमांड चला रहे हैं वह क्या करेगा, यह सिर्फ एक के आउटपुट को दूसरे के इनपुट से जोड़ता है।

यदि grep"हैलो दुनिया" कहने वाली 10 से अधिक लाइनें मिलती हैं, headतो सभी 10 लाइनें होंगी जो इसे चाहती हैं, और पाइप को बंद करें। यह grepएक SIGPIPE के साथ मारे जाने का कारण होगा , इसलिए इसे बहुत बड़ी फ़ाइल को स्कैन करना जारी रखने की आवश्यकता नहीं है।


2
तो मुझे लगता है, दौड़ की स्थिति के कारण, grep ने 11 वीं या 12 वीं पैटर्न पहले ही पढ़ लिया होगा, लेकिन शायद 100 हजार नहीं?
यूजर अनजान

3
यह लाइनों की लंबाई और पाइप बफर के आकार पर निर्भर करता है, लेकिन संक्षिप्त उत्तर यह है कि grep मारे जाने से पहले कुछ हद तक अतिरिक्त डेटा पढ़ेगा।
dmckee

1
@userunknown, बिल्कुल।
Psusi

कूल, मुझे नहीं पता था कि ऐसा हुआ था। मैंने सोचा था कि grepएक शून्य में आउटपुट भेजना जारी रहेगा, जैसे कि/dev/null
इजाकाटा

15

जब कोई प्रोग्राम पाइप में लिखने की कोशिश करता है और उस पाइप से पढ़ने की कोई प्रक्रिया नहीं होती है, तो लेखक प्रोग्राम को एक SIGPIPE सिग्नल मिलता है। जब कोई प्रोग्राम SIGPIPE प्राप्त करता है तो डिफ़ॉल्ट क्रिया प्रोग्राम को समाप्त करना है। कोई प्रोग्राम SIGPIPE सिग्नल को नजरअंदाज करने का विकल्प चुन सकता है, जिस स्थिति में राइट एक एरर ( EPIPE) देता है।

आपके उदाहरण में, यहाँ क्या होता है की एक समयावधि है:

  • grepऔर headआदेशों समानांतर में शुरू।
  • grep कुछ इनपुट पढ़ता है, इसे संसाधित करना शुरू करता है।
  • कुछ बिंदु पर, grepआउटपुट का पहला हिस्सा पैदा करता है।
  • head पढ़ता है कि पहले उसे काटता है और उसे लिखता है।
  • मान लें कि पहले 10 मैचों के बाद पर्याप्त लाइनें हैं (अन्यथा grepपहले समाप्त हो सकती हैं), आखिरकार headवांछित संख्याओं को मुद्रित किया जाएगा। इस बिंदु पर, headबाहर निकलता है।
  • grepऔर headप्रक्रियाओं की सापेक्ष गति के आधार पर , grepकुछ डेटा संचित हो सकता है और इसे अभी तक प्रिंट नहीं किया गया है। समय headनिकलने पर, grepइनपुट पढ़ना या आंतरिक प्रसंस्करण करना हो सकता है, जिस स्थिति में यह ऐसा करना जारी रखेगा।
  • जल्द ही grepइसके द्वारा संसाधित किए गए डेटा को लिख देगा। उस बिंदु पर, यह एक हस्ताक्षर प्राप्त करेगा और मर जाएगा।

यह संभावना है कि grepकड़ाई से आवश्यक से थोड़ा अधिक इनपुट संसाधित करेगा, लेकिन आम तौर पर केवल कुछ किलोबाइट होते हैं:

  • headआम तौर पर कुछ किलोबाइट्स के अंशों में पढ़ता है (क्योंकि यह readप्रत्येक बाइट के लिए एक सिस्टम कॉल जारी करने से अधिक कुशल है - इस व्यवहार को बफरिंग कहा जाता है), इसलिए वांछित अंतिम पंक्ति के समाप्त होने के बाद अंतिम चंक का शेष भाग।
  • पारगमन में कुछ डेटा हो सकता है, क्योंकि पाइप में एक संबद्ध बफर कर्नेल (अक्सर 512 बाइट्स) द्वारा प्रबंधित होता है। यह डेटा छोड़ दिया जाएगा।
  • grepकुछ डेटा संचित हो सकता है जो आउटपुट चंक बनने के लिए तैयार है (फिर से बफरिंग)। जब यह अपने आउटपुट बफर को फ्लश करने की कोशिश कर रहा है तो यह SIGPIPE प्राप्त करेगा।

सभी प्रणाली में सभी को ठीक से डिज़ाइन किया गया है ताकि फ़िल्टरिंग उपयोगिताओं को स्वाभाविक रूप से कुशलता से व्यवहार किया जा सके। जब उनके आउटपुट चैनल की मृत्यु हो जाती है, तो ऐसे कार्यक्रमों को जारी रखने की आवश्यकता होती है जो SIGPIPE सिग्नल की अनदेखी करने का कदम उठाते हैं।


3

Sortof, पाइपलाइन इस तरह से काम करता है: यह पहले पहले कमांड को निष्पादित करता है और फिर आपके मामले में दूसरा कमांड।

यही है, चलो A|Bआज्ञा दी गई है। फिर यह अनिश्चित है कि पहले शुरू होता है Aया नहीं B। यदि एक से अधिक CPU हैं तो वे ठीक उसी समय शुरू हो सकते हैं। एक पाइप डेटा की एक अपरिभाषित लेकिन सीमित मात्रा में पकड़ सकता है।

यदि बी पाइप से पढ़ने की कोशिश करता है, लेकिन कोई डेटा उपलब्ध नहीं है, Bतो डेटा आने तक इंतजार करेगा। यदि Bएक डिस्क से पढ़ रहा था, Bतो एक ही समस्या हो सकती है और तब तक इंतजार करना पड़ता है जब तक कि डिस्क रीड खत्म न हो जाए। एक कीबोर्ड से एक निकट सादृश्य पढ़ा जाएगा। वहां, Bउपयोगकर्ता को टाइप करने के लिए इंतजार करना होगा। लेकिन इन सभी मामलों में, बी ने एक "रीड" ऑपरेशन शुरू किया है और इसे खत्म होने तक इंतजार करना चाहिए। लेकिन अगर Bकोई ऐसा कमांड है, जिसे Aकुछ बिंदुओं के बाद केवल आंशिक उत्पादन की आवश्यकता होती है, जहां Bएस इनपुट स्तर तक पहुंच जाता है A, तो उसे एसआईजीपीईटी द्वारा मार दिया जाएगा

यदि Aपाइप में लिखने की कोशिश की जाती है और पाइप भरा हुआ है, तो पाइप Aके कुछ कमरे के खाली होने का इंतजार करना चाहिए। Aएक ही समस्या हो सकती है अगर यह एक टर्मिनल को लिख रहा था। एक टर्मिनल में प्रवाह नियंत्रण होता है और यह डेटा की गति को मध्यम कर सकता है। किसी भी घटना में, Aइसने एक "लिखना" ऑपरेशन शुरू किया है और तब तक प्रतीक्षा करेगा जब तक कि लेखन कार्य समाप्त नहीं हो जाता।

Aऔर Bसह-प्रक्रियाओं के रूप में व्यवहार कर रहे हैं, हालांकि सभी सह-प्रक्रिया एक पाइप के साथ संचार नहीं करेंगे। न ही दूसरे के पूर्ण नियंत्रण में है।


1
सवाल यह है: "जब A पाइप के किनारे को बंद कर देगा तो A क्या करेगा?"
enzotib

2
क्या वह 'टूटा हुआ पाइप' नहीं होगा?
पटकोस सेबा

1
यदि कोई प्रोग्राम बंद पाइप (जैसे headबाहर निकलता है) से पढ़ने / लिखने की कोशिश करता है, तो प्रोग्राम में एक SIGPIPE सिग्नल होता है और डिफ़ॉल्ट व्यवहार बाहर निकलने के लिए होता है।
लीकेनस्टेन

यह प्रश्न का उत्तर कैसे देता है? ऐसा लगता है कि psusi का उत्तर कम और बिंदु तक अधिक है।
20 जून को jw013

1

grepपाइप का कोई प्रत्यक्ष नियंत्रण नहीं है (यह सिर्फ डेटा प्राप्त कर रहा है), और पाइप का कोई प्रत्यक्ष नियंत्रण नहीं है grep(यह सिर्फ डेटा भेज रहा है) ...

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

टर्मिनल वैसे ही काफी की आंतरिक कार्यप्रणाली से काट दिया है grepऔर shellकी पाइपिंग क्रियाएँ ... टर्मिनल मूल रूप से सिर्फ एक शुरूआत पैड, और आउटपुट प्रदर्शन है ...

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