दो बार खुद को विशिष्ट शेल "फोर्क बम" कैसे कहते हैं?


15

Askubuntu और कई अन्य स्टैक एक्सचेंज साइटों पर प्रसिद्ध फोर्क बम प्रश्नों के माध्यम से जाने के बाद , मुझे यह बिल्कुल समझ में नहीं आया कि हर कोई क्या कह रहा है जैसे यह स्पष्ट है।

कई जवाब ( सर्वश्रेष्ठ उदाहरण ) यह कहते हैं:

"का {:|: &}अर्थ है फंक्शन को रन करना :और :फिर से फंक्शन में अपना आउटपुट भेजना "

ठीक है, क्या वास्तव में उत्पादन है :? दूसरे को क्या दिया जा रहा है :?

और भी:

अनिवार्य रूप से आप एक ऐसा फंक्शन बना रहे हैं जो हर कॉल को दो बार कॉल करता है और खुद को समाप्त करने का कोई तरीका नहीं है।

यह वास्तव में दो बार कैसे निष्पादित किया जाता है ? मेरी राय में, कुछ भी दूसरे को :तब तक पारित नहीं किया जाता है जब तक कि पहला :अपना निष्पादन समाप्त नहीं कर देता है, जो वास्तव में कभी समाप्त नहीं होगा।

में Cउदाहरण के लिए,

foo()
{
    foo();
    foo(); // never executed 
}

दूसरे foo()का निष्पादन नहीं किया जाता है, सिर्फ इसलिए कि पहला foo()कभी समाप्त नहीं होता है।

मैं सोच रहा हूं कि वही तर्क लागू होता है :(){ :|: & };:और

:(){ : & };:

जैसा काम करता है वैसा ही करता है

:(){ :|: & };:

कृपया मुझे तर्क समझने में मदद करें।


9
पाइपलाइनों में कमांड समानांतर में चलती है, :|:दूसरा :, पहले पूरा होने की प्रतीक्षा करने की आवश्यकता नहीं है।
cuonglm

जवाबों:


26

पाइपिंग की आवश्यकता नहीं है कि दूसरा शुरू होने से पहले पहला उदाहरण पूरा हो जाए। वास्तव में, सभी यह वास्तव में क्या कर रही है पुनः निर्देशित है 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 उदाहरण -> ...

जैसा कि आप देख सकते हैं, बैकग्राउंड में फ़ंक्शन को कॉल करना (उपयोग करना &) वास्तव में फोर्क बम को धीमा कर देता है, क्योंकि कॉलली को फंक्शंस के वापस आने से पहले छोड़ दिया जाएगा।


सवाल। :(){ : & && : &}; :फोर्क बम के रूप में भी काम करेगा ? आप तेजी से वृद्धि भी करेंगे, और, वास्तव में, आप : &इसे और भी तेजी से बढ़ाने के लिए इसमें कई गुणक लगा सकते हैं ।
JFA

@ जेएफए `J> $: () {: & &&: &}; : `सिंटैक्स त्रुटि देता है bash: syntax error near unexpected token &&' । आप ऐसा कर सकते हैं: :(){ $(: &) && $(: &)}; :लेकिन फिर से, पाइपलाइन के विपरीत, जो समानांतर नहीं चलेगा। जिसके बराबर होगा :(){: & };:। सत्यापित करना पसंद है? इन्हें आज़माएं time $( $(sleep 1 & ) && $(sleep 1 &) )और यहtime $(sleep 1 | sleep 1)
सेवेरस टक्स

वास्तव में, :(){ $(: &) && $(: &)};एक फ़ंक्शन है जो पहले और दूसरे उदाहरण के रिटर्न मानों में एक तार्किक और ऑपरेशन जारी कर रहा है। समस्या यह है, क्योंकि एक तार्किक और केवल सच है यदि दोनों मान सत्य हैं, तो दक्षता के लिए केवल पहला उदाहरण चलाया जाएगा। यदि इसका रिटर्न वैल्यू 1 है तो दूसरा उदाहरण चलेगा। यदि आप कांटा बम को और भी तेज बनाना चाहते हैं, तो मुझे लगता है कि आप श्रृंखला में अधिक उदाहरणों को पाइप कर सकते हैं, जैसे:(){ :|:|: &}; :
IanC

एक साइड नोट के रूप में, कई स्क्रिप्ट निम्नलिखित स्थिति में AND के इस व्यवहार का उपयोग करती हैं: यदि आप prog1 को सही मानते हैं तो prog2 को चलाना चाहते हैं (जो bash में 0 है)। एक if-statement ( if [ prog1 ]; then; prog2; fi) करने के बजाय आप सिर्फ लिख सकते हैं ( prog1 && prog2), और prog2 तभी चलेगा जब prog1 का रिटर्न वैल्यू सही था।
IanC

ठीक है, ये सभी महान बिंदु हैं। मैं &&कॉल करने के लिए उपयोग करता हूं apt-get update && apt-get upgrade, और &पृष्ठभूमि में चलाने के लिए लाइन के अंत में, लेकिन यह बहुत अच्छा बिंदु है कि वे एक साथ काम नहीं करेंगे। एक अर्धविराम भी एम्परसेंड के साथ काम नहीं करता है।
JFA
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.