पाइपिंग की आवश्यकता नहीं है कि दूसरा शुरू होने से पहले पहला उदाहरण पूरा हो जाए। वास्तव में, सभी यह वास्तव में क्या कर रही है पुनः निर्देशित है stdout करने के लिए पहले उदाहरण के stdin दूसरा एक की है, ताकि वे एक साथ चल जा सकता है (वे काम करने के लिए कांटा बम के लिए करने के लिए है के रूप में)।
ठीक है, क्या वास्तव में उत्पादन है :
? दूसरे को क्या दिया जा रहा है :
?
':' दूसरे के लिए कुछ भी नहीं लिख रहा है ':' उदाहरण है, यह सिर्फ पुनः निर्देशित है stdout को stdin दूसरे उदाहरण के। यदि यह अपने निष्पादन के दौरान कुछ लिखता है (जो यह कभी नहीं होगा, क्योंकि यह कुछ भी नहीं करता है, लेकिन खुद को मजबूर करता है) यह दूसरे उदाहरण के स्टैडेन पर जाएगा।
यह कल्पना करने में मदद करता stdin और stdout एक ढेर के रूप में:
जो कुछ भी स्टड को लिखा जाता है, वह उस समय के लिए तैयार हो जाता है, जब प्रोग्राम उसमें से पढ़ने का फैसला करता है, जबकि स्टडआउट उसी तरह काम करता है: एक ढेर जिसे आप लिख सकते हैं, इसलिए अन्य प्रोग्राम इसे तब से पढ़ सकते हैं जब वे चाहते हैं।
इस तरह यह एक पाइप जैसी स्थितियों की कल्पना करना आसान है जिसमें कोई संचार नहीं हो रहा है (दो खाली ढेर) या गैर-सिंक्रनाइज़ किए गए लिखते हैं और पढ़ते हैं।
यह वास्तव में दो बार कैसे निष्पादित किया जाता है? मेरी राय में, कुछ भी दूसरे को :
तब तक पारित नहीं किया जाता है जब तक कि पहला :
अपना निष्पादन समाप्त नहीं कर देता है, जो वास्तव में कभी समाप्त नहीं होगा।
चूँकि हम उदाहरणों के इनपुट और आउटपुट को पुनर्निर्देशित कर रहे हैं, इसलिए दूसरे के शुरू होने से पहले समाप्त होने के लिए पहले उदाहरण की कोई आवश्यकता नहीं है। यह वास्तव में आम तौर पर वांछित है कि दोनों एक साथ चलते हैं इसलिए दूसरा मक्खी पर पहले एक द्वारा डेटा पार्स होने के साथ काम कर सकता है। यहां ऐसा ही होता है, दोनों को पहले खत्म होने की प्रतीक्षा किए बिना बुलाया जाएगा। यह आदेशों के सभी पाइप श्रृंखला लाइनों पर लागू होता है ।
मैं सोच रहा हूं कि एक ही तर्क लागू होता है: () {: |: &} ;:?
:(){ : & };:
जैसा काम करता है वैसा ही करता है
:(){ :|: & };:
पहला काम नहीं करेगा, क्योंकि भले ही यह पुनरावर्ती रूप से चल रहा हो, लेकिन पृष्ठभूमि में फ़ंक्शन को बुलाया जा रहा है ( : &
)। पहला :
बच्चा तब तक इंतजार नहीं करता है जब तक कि "बच्चा" :
खुद को समाप्त करने से पहले वापस नहीं आता है, इसलिए अंत में आपके पास केवल :
चलने का एक उदाहरण होगा । यदि आपके पास :(){ : };:
यह काम होता, हालांकि, पहले :
"बच्चे" :
के लौटने का इंतजार करता, जो अपने "बच्चे" :
के लौटने का इंतजार करता , और इसी तरह।
यहां विभिन्न उदाहरणों के चलने के संदर्भ में अलग-अलग कमांड दिखेंगे।
:(){ : & };:
1 उदाहरण (कॉल :
और क्विट्स) -> 1 उदाहरण (कॉल :
और क्विट्स) -> 1 उदाहरण (कॉल :
और क्विट्स) -> १ उदाहरण -> ...
:(){ :|: &};:
1 उदाहरण (कॉल 2 :
's और क्विट्स) -> 2 इंस्टेंस (प्रत्येक एक 2 कॉल :
s और क्विट्स) -> 4 इंस्टेंस (प्रत्येक एक 2 कॉल :
और क्विट्स) -> 8 इंस्टेंस -> ...
:(){ : };:
1 उदाहरण (कॉल :
और इसके लौटने की प्रतीक्षा करता है) -> 2 इंस्टेंस (बच्चा दूसरे को कॉल :
करता है और उसके लौटने का इंतजार करता है) -> 3 इंस्टेंस (बच्चा दूसरे को कॉल :
करता है और उसके लौटने का इंतजार करता है) -> 4 इंस्टेंस -> ...
:(){ :|: };:
1 उदाहरण (कॉल 2 :
की प्रतीक्षा करता है और उनके लौटने का इंतजार करता है) -> 3 उदाहरण (बच्चे 2 के कॉल :
करते हैं और प्रत्येक के लौटने का इंतजार करते हैं) -> 7 उदाहरण (बच्चे 2 :
के प्रत्येक को कॉल करते हैं और उनके लौटने का इंतजार करते हैं) -> 15 उदाहरण -> ...
जैसा कि आप देख सकते हैं, बैकग्राउंड में फ़ंक्शन को कॉल करना (उपयोग करना &
) वास्तव में फोर्क बम को धीमा कर देता है, क्योंकि कॉलली को फंक्शंस के वापस आने से पहले छोड़ दिया जाएगा।
:|:
दूसरा:
, पहले पूरा होने की प्रतीक्षा करने की आवश्यकता नहीं है।