ये बैश कांटा बम अलग तरीके से क्यों काम करते हैं और इसमें क्या महत्व है?


16

मुझे लगता है कि एक सामान्य कांटा बम कैसे काम करता है, लेकिन मुझे वास्तव में समझ में नहीं आता कि & bash फोर्क बम के अंत में क्यों आवश्यक है और इन लिपियों में भिन्न व्यवहार क्यों होता है:

:(){ (:) | (:) }; :

तथा

:(){ : | :& }; :

पहले मुझे लॉगिन स्क्रीन पर वापस लाने से पहले एक CPU उपयोग स्पाइक का कारण बनता है। इसके बजाय उत्तरार्द्ध बस मेरे सिस्टम को स्थिर करने का कारण बनता है, मुझे कठिन रिबूट के लिए मजबूर करता है। ऐसा क्यों है? दोनों लगातार नई प्रक्रियाएं बनाते हैं, तो सिस्टम अलग तरह से व्यवहार क्यों करता है?

दोनों लिपियाँ भी अलग-अलग व्यवहार करती हैं

:(){ : | : }; :

जो किसी भी समस्या का कारण नहीं है, भले ही मैंने उनसे एक जैसे होने की उम्मीद की होगी। बैश मैनुअल पेज में कहा गया है कि एक पाइपलाइन में कमांड पहले से ही एक सब-टाइम में निष्पादित होते हैं, इसलिए मुझे विश्वास है कि: | : पहले से ही पर्याप्त होना चाहिए। मैं विश्वास करता हूं और बस एक नई उपधारा में पाइपलाइन चलाना चाहिए, लेकिन यह इतना परिवर्तन क्यों करता है?

संपादित करें: htop का उपयोग करना और प्रक्रियाओं की मात्रा को सीमित करना, मैं यह देखने में सक्षम था कि पहला संस्करण प्रक्रियाओं का एक वास्तविक पेड़ बनाता है, दूसरा संस्करण एक ही स्तर पर सभी प्रक्रियाओं को बनाता है और अंतिम संस्करण किसी भी प्रक्रिया को बनाने के लिए प्रतीत नहीं होता है बिल्कुल भी। यह मुझे और भी भ्रमित करता है, लेकिन शायद यह किसी तरह मदद करता है?


2
मुझे लगता है कि आपका अंतिम संस्करण अर्धविराम याद कर रहा है::(){ : | :; }; :
एडोनिस

जवाबों:


22

उत्पादन मशीन पर दौड़ने के लिए चेतावनी नहीं है। बस नहीं है। चेतावनी: किसी भी "बम" का प्रयास करने के लिए सुनिश्चित करें कि ulimit -uउपयोग में है। नीचे पढ़ें [a]

चलो पीआईडी ​​और तारीख (समय) प्राप्त करने के लिए एक फ़ंक्शन को परिभाषित करते हैं:

bize:~$ d(){ printf '%7s %07d %s\n' "$1" "$BASHPID" "$(date +'%H:%M:%S')"; }

bombनए उपयोगकर्ता के लिए एक सरल, गैर-जारी समारोह (खुद को सुरक्षित रखें: [क] पढ़ें ):

bize:~$ bomb() { d START; echo "yes"; sleep 1; d END; } >&2

जब उस कार्य को इस प्रकार निष्पादित किया जाता है:

bize:~$ bomb
  START 0002786 23:07:34
yes
    END 0002786 23:07:35
bize:~$

कमांड dateको निष्पादित किया जाता है, फिर एक "हां" मुद्रित किया जाता है, 1 सेकंड के लिए एक नींद, फिर समापन कमांड dateऔर, अंत में, फ़ंक्शन नए कमांड प्रॉम्प्ट को प्रिंट करने से बाहर निकलता है। कुछ भी आकर्षक नहीं।

| पाइप

जब हम फ़ंक्शन को इस तरह कहते हैं:

bize:~$ bomb | bomb
  START 0003365 23:11:34
yes
  START 0003366 23:11:34
yes
    END 0003365 23:11:35
    END 0003366 23:11:35
bize:~$

दो कमांड कुछ समय में शुरू हो जाती हैं, दो अंत 1 सेकंड और फिर शीघ्र वापस आती हैं।

पाइप का कारण |, समानांतर में दो प्रक्रियाएं शुरू करना है।

& पृष्ठभूमि

यदि हम कॉल को समाप्त करते हुए बदलते हैं &:

bize:~$ bomb | bomb &
[1] 3380
bize:~$
  START 0003379 23:14:14
yes
  START 0003380 23:14:14
yes
    END 0003379 23:14:15
    END 0003380 23:14:15

तुरंत संकेत मिलता है (सभी कार्रवाई पृष्ठभूमि पर भेजी जाती है) और दोनों कमांड पहले की तरह निष्पादित हो जाते हैं। कृपया [1]प्रक्रिया के पीआईडी ​​से पहले मुद्रित "नौकरी नंबर" का मूल्य नोट करें 3380। बाद में, यह बताने के लिए कि पाइप खत्म हो गया है, उसी नंबर को प्रिंट किया जाएगा:

[1]+  Done                    bomb | bomb

का प्रभाव है &

इसका कारण यह है &: प्रक्रियाओं को तेजी से शुरू करने के लिए।

सरल नाम

हम एक bकमांड बना सकते हैं, जिसे केवल दो कमांड्स निष्पादित करने के लिए कहा जाता है । तीन पंक्तियों में टाइप किया गया:

bize:~$ b(){
> bomb | bomb
> }

और के रूप में निष्पादित:

bize:~$ b
  START 0003563 23:21:10
yes
  START 0003564 23:21:10
yes
    END 0003564 23:21:11
    END 0003563 23:21:11

ध्यान दें कि हमने कोई ;परिभाषा का उपयोग नहीं किया था b(नए तत्वों को अलग-अलग तत्वों के लिए उपयोग किया गया था)। हालांकि, एक लाइन पर परिभाषा के लिए ;, इस तरह का उपयोग करना सामान्य है :

bize:~$ b(){ bomb | bomb ; }

अधिकांश स्थान भी अनिवार्य नहीं हैं, हम समकक्ष (लेकिन कम स्पष्ट) लिख सकते हैं:

bize:~$ b(){ bomb|bomb;}

हम एक &को अलग करने के लिए }(और बैकग्राउंड में दो प्रक्रियाएँ भेजने के लिए) का उपयोग कर सकते हैं ।

बम।

यदि हम फ़ंक्शन को अपनी पूंछ काटते हैं (स्वयं कॉल करके), तो हमें "कांटा बम" मिलता है:

bize:~$ b(){ b|b;}       ### May look better as b(){ b | b ; } but does the same.

और इसे और अधिक फ़ंक्शन कॉल करने के लिए, पृष्ठभूमि पर पाइप भेजें।

bize:~$ b(){ b|b&}       ### Usually written as b(){ b|b& }

यदि हम आवश्यक होने के बाद फ़ंक्शन को पहली कॉल देते ;हैं और नाम को :हम प्राप्त करते हैं:

bize:~$ :(){ :|:&};:

आमतौर पर जैसा लिखा जाता है :(){ :|:& }; :

या, एक मजेदार तरीके से लिखा गया है, किसी अन्य नाम (एक हिम-पुरुष) के साथ:

☃(){ ☃|☃&};☃

Ulimit (जिसे आपको इसे चलाने से पहले सेट करना चाहिए था) बहुत त्रुटियों के बाद शीघ्र वापसी कर देगा (प्रेस सूची जब प्रॉम्प्ट प्राप्त करने के लिए बंद हो जाती है)।

इसे "कांटा बम" कहा जाने का कारण यह है कि जिस तरह से शेल एक सब-शेल शुरू करता है वह रनिंग शेल को फोर्क करने और फिर रन करने के लिए कमांड के साथ फोर्कड प्रोसेस को निष्पादन () बुलाता है।

एक पाइप दो नई प्रक्रियाओं को "कांटा" करेगा। अनंत करने के लिए यह एक बम का कारण बनता है।
या एक खरगोश के रूप में मूल रूप से बुलाया गया था क्योंकि यह इतनी जल्दी प्रजनन करता है।


समय:

  1. :(){ (:) | (:) }; time :
    समाप्त
    वास्तविक 0m45.627s

  2. :(){ : | :; }; time :
    समाप्त
    वास्तविक 0m15.283s

  3. :(){ : | :& }; time :
    असली 0m00.002
    अभी भी चल रहा है


आपके उदाहरण:

  1. :(){ (:) | (:) }; :

    जहां दूसरा समापन )अलग है, }का एक और अधिक जटिल संस्करण है :(){ :|:;};:। एक पाइप में प्रत्येक कमांड को वैसे भी सब-शेल के अंदर कहा जाता है। जिसका असर है ()

  2. :(){ : | :& }; :

    तेज़ संस्करण है, जिसमें कोई स्थान नहीं है: :(){(:)|:&};:(13 वर्ण)।

  3. :(){ : | : }; : ### zsh में काम करता है लेकिन bash में नहीं।

    एक सिंटैक्स त्रुटि (बैश में), एक metacharacter समापन से पहले की जरूरत है है },
    इस रूप में:

    :(){ : | :; }; :

[a] एक नया स्वच्छ उपयोगकर्ता बनाएं (मैं अपना फोन करूंगाbize)। इस नए उपयोगकर्ता को कंसोल में लॉगिन करेंsudo -i -u bize, या:

$ su - bize
Password: 
bize:~$

जाँच करें और फिर max user processesसीमा बदलें :

bize:~$ ulimit -a           ### List all limits (I show only `-u`)
max user processes              (-u) 63931
bize:~$ ulimit -u 10        ### Low
bize:~$ ulimit -a
max user processes              (-u) 1000

केवल एक ही नए उपयोगकर्ता के रूप में केवल 10 कार्यों का उपयोग करना bize:। कॉल करने killall -u bizeऔर सिस्टम को सबसे अधिक (सभी नहीं) से छुटकारा पाने में आसान बनाता है । कृपया यह न पूछें कि अभी भी कौन से काम करते हैं, मैं नहीं बताऊंगा। लेकिन फिर भी: काफी कम है, लेकिन सुरक्षित पक्ष पर, अपने सिस्टम के अनुकूल है
यह सुनिश्चित करेगा कि "फोर्क बम" आपके सिस्टम को ध्वस्त नहीं करेगा

आगे की पढाई:

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