সাধারণত শেল "কাঁটাচামচ" কীভাবে নিজেকে দু'বার কল করে?


15

এসকুবুন্টু এবং অন্যান্য অনেক স্ট্যাক এক্সচেঞ্জ সাইটে বিখ্যাত ফর্ক বোমা প্রশ্নগুলির পরে, আমি প্রত্যক্ষভাবে বুঝতে পারি না যে প্রত্যেকে কী বলছে এটি সুস্পষ্ট।

অনেক উত্তর ( সেরা উদাহরণ ) এটি বলে:

"এর {:|: &}অর্থ ফাংশনটি চালান :এবং এর ফলাফলটি :আবার ফাংশনে প্রেরণ করুন "

ঠিক আছে, আউটপুট ঠিক কি: ? অন্যের কাছে কী পাস হচ্ছে :?

এবং যদিও:

মূলত আপনি এমন একটি ফাংশন তৈরি করছেন যা প্রতি কলটিতে নিজেকে দু'বার কল করে এবং নিজেকে শেষ করার কোনও উপায় নেই।

কিভাবে ঠিক দুইবার মৃত্যুদন্ড কার্যকর করা হয় ? আমার মতে, :প্রথমটি :কার্যকর করা শেষ না হওয়া পর্যন্ত দ্বিতীয়টিতে কিছুই পাস করা হয় না , যা আসলে কখনও শেষ হয় না।

ইন Cউদাহরণস্বরূপ,

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

দ্বিতীয়টি foo()মোটেও কার্যকর করা হয় না, কারণ প্রথমটি foo()কখনই শেষ হয় না।

আমি ভাবছি যে একই যুক্তি প্রয়োগ হয় :(){ :|: & };:এবং

:(){ : & };:

হিসাবে একই কাজ করে

:(){ :|: & };:

আমাকে যুক্তি বুঝতে সাহায্য করুন।


9
পাইপলাইনগুলিতে কমান্ড সমান্তরালভাবে চালিত হয়, :|:দ্বিতীয়টি :প্রথমটি সম্পন্ন হওয়া অপেক্ষা করতে হবে না।
cuonglm

উত্তর:


26

পাইপিংয়ের প্রয়োজন হয় না যে অন্যটি শুরু হওয়ার আগে প্রথম উদাহরণটি শেষ হয়। আসলে, সব সত্যিই করছে পুনঃচালিত হচ্ছে stdout- এ প্রথম ইনস্ট্যান্সের stdin দ্বিতীয় এক, তাই তারা একসঙ্গে চলছে করা যেতে পারে (তারা কাজ কাঁটাচামচ বোমা জন্য আছে হিসাবে)।

ঠিক আছে, আউটপুট ঠিক কি :? অপরকে :কী দেওয়া হচ্ছে ?

':' অন্য কিছু লেখা হয় না ':' উদাহরণ হিসেবে বলা যায়, এটা ঠিক পুনঃনির্দেশিত হচ্ছে stdout- এ থেকে stdin দ্বিতীয় উদাহরণ হিসেবে বলা যায় এর। এটি কার্যকর করার সময় যদি এটি কিছু লিখে থাকে (যা এটি কখনই হবে না, যেহেতু এটি নিজেই কাঁটাচামচ করা ছাড়া কিছুই করে না) এটি অন্য উদাহরণের স্টিডিনের কাছে যাবে।

এটি স্টিন এবং স্টডআউটকে একটি স্তূপ হিসাবে কল্পনা করতে সহায়তা করে :

স্ট্যান্ডিনকে যা কিছু লেখা আছে তা যখন প্রোগ্রামটি পড়ার সিদ্ধান্ত নেয় তখন তার জন্য প্রস্তুত স্তূপটি তৈরি করা হবে, যখন স্টাডাউট একইভাবে কাজ করে: আপনি যে স্তূপে লিখতে পারেন, তাই অন্যান্য প্রোগ্রামগুলি যখন ইচ্ছা তখন তা পড়তে পারে।

এইভাবে কোনও পাইপের মতো পরিস্থিতি কল্পনা করা সহজ যে কোনও যোগাযোগ ঘটছে না (দুটি খালি পাইলস) বা নন-সিঙ্ক্রোনাইজড লিখন এবং পঠন।

কিভাবে ঠিক দুইবার মৃত্যুদন্ড কার্যকর করা হয়? আমার মতে, :প্রথমটি :কার্যকর করা শেষ না হওয়া পর্যন্ত দ্বিতীয়টিতে কিছুই পাস করা হয় না , যা আসলে কখনও শেষ হয় না।

যেহেতু আমরা কেবল উদাহরণগুলির ইনপুট এবং আউটপুটটিকে পুনর্নির্দেশ করছি, তাই দ্বিতীয়টি শুরু হওয়ার আগে প্রথম দৃষ্টান্তটি শেষ করার দরকার নেই। এটি প্রকৃতপক্ষে কাঙ্ক্ষিত যে উভয়ই একই সাথে চলুক যাতে দ্বিতীয়টি ফ্লাইতে থাকা প্রথম দ্বারা পার্স করা ডেটার সাথে কাজ করতে পারে। এখানেই এটি ঘটে, উভয়কেই প্রথম সমাপ্তির জন্য অপেক্ষা না করে ডাকা হবে। এটি কমান্ডের সমস্ত পাইপ চেইন লাইনের ক্ষেত্রে প্রযোজ্য ।

আমি ভাবছি যে একই যুক্তি প্রযোজ্য: () {: |: &} ;: এবং

:(){ : & };:

হিসাবে একই কাজ করে

:(){ :|: & };:

প্রথমটি কাজ করবে না, কারণ এটি নিজেকে পুনরাবৃত্তভাবে চালিত করার পরেও ফাংশনটি পটভূমিতে ডাকা হচ্ছে ( : &)। :"বাচ্চা" :নিজের শেষ হওয়ার আগে ফিরে না আসা পর্যন্ত প্রথমটি অপেক্ষা করে না , সুতরাং শেষ পর্যন্ত আপনার সম্ভবত :দৌড়ানোর একটি উদাহরণ থাকবে । :(){ : };:যদিও আপনার যদি এটি কাজ করে তবে প্রথমটি :"সন্তানের" :প্রত্যাবর্তনের জন্য অপেক্ষা করত, যা তার নিজের "সন্তানের" :প্রত্যাবর্তনের জন্য অপেক্ষা করত , এবং আরও অনেক কিছু।

কতগুলি দৃষ্টান্ত চলমান থাকবে তার বিবিধ আদেশগুলি দেখতে কেমন তা এখানে রয়েছে:

:(){ : & };:

1 টি উদাহরণ (কল :এবং প্রস্থান) -> 1 দৃষ্টান্ত (কল :এবং প্রস্থান) -> 1 দৃষ্টান্ত (কল :এবং প্রস্থান) -> 1 দর্শন -> ...

:(){ :|: &};:

1 দৃষ্টান্ত (2 :'s এবং প্রস্থানগুলি কল করুন ) -> 2 টি দৃষ্টান্ত (প্রত্যেকে কল 2 :এর এবং প্রস্থানগুলি কল করে ) -> 4 টি দৃষ্টান্ত (প্রত্যেকে প্রত্যেকে 2 :এর এবং প্রস্থানকে কল করে ) -> 8 টি দৃষ্টান্ত -> ...

:(){ : };:

1 দৃষ্টান্ত (কল :ফিরে আসে এবং এটি ফিরে আসার জন্য অপেক্ষা করে) -> 2 টি দৃষ্টান্ত (শিশু অন্যজনকে কল করে :এবং এটি ফিরে আসার জন্য অপেক্ষা করে) -> 3 টি দৃষ্টান্ত (শিশু অন্যজনকে কল করে :এবং এটি ফিরে আসার জন্য অপেক্ষা করে) -> 4 টি দৃষ্টান্ত -> ...

:(){ :|: };:

1 টি উদাহরণ (2 :এর কল করে এবং তাদের ফিরে আসার জন্য অপেক্ষা করে) -> 3 টি দৃষ্টান্ত (শিশুরা :প্রত্যেকে 2 টি কল করে এবং তাদের ফিরে আসার জন্য অপেক্ষা করবে) -> 7 টি দৃষ্টান্ত (শিশুরা :প্রত্যেকে 2 টি কল করে এবং তাদের ফিরে আসার জন্য অপেক্ষা করবে) -> 15 টি দৃষ্টান্ত -> ...

আপনি দেখতে পাচ্ছেন, ব্যাকগ্রাউন্ডে ফাংশনটি কল করা (ব্যবহার করে &) কাঁটাচামচ বোমাটি ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে বেড়ে যায়।


প্রশ্ন। :(){ : & && : &}; :এছাড়াও কাঁটাচামচ বোমা হিসাবে কাজ করবে ? আপনি তাত্পর্যপূর্ণভাবে বৃদ্ধি করতে পারবেন এবং প্রকৃতপক্ষে, আপনি : &এটি আরও দ্রুত বাড়ানোর জন্য একাধিক স্থানে রাখতে পারেন।
জেএফএ

@ জেএফএ `─> $: () {: &&&: &}; : synt সিনট্যাক্স ত্রুটি দেয় bash: syntax error near unexpected token &&' । আপনি এটি করতে পারেন :(){ $(: &) && $(: &)}; ::, তবে আবার পাইপলাইন থেকে পৃথক, এটি সমান্তরালভাবে চলবে না। যার সমতুল্য হবে :(){: & };:। যাচাই করতে চান? এগুলি time $( $(sleep 1 & ) && $(sleep 1 &) )এবং এটি ব্যবহার করে দেখুনtime $(sleep 1 | sleep 1)
সেভেরাস টাক্স

হুবহু, এটি :(){ $(: &) && $(: &)};একটি ফাংশন যা প্রথম এবং দ্বিতীয় উদাহরণের রিটার্ন মানগুলিতে একটি লজিকাল এবং অপারেশন জারি করে। সমস্যাটি হ'ল যেহেতু একটি যৌক্তিক AND কেবলমাত্র সত্য যদি উভয় মানই সত্য হয় তবে দক্ষতার জন্য কেবল প্রথম উদাহরণটি চালিত হবে। যদি এর রিটার্ন মান 1 হয় তবে দ্বিতীয় উদাহরণটি চলবে। আপনি যদি কাঁটাচামচ বোমাটি আরও দ্রুত তৈরি করতে চান তবে আমার মনে হয় আপনি কেবল চেইনে আরও :(){ :|:|: &}; :
কয়েকটি

একটি পার্শ্ব নোট হিসাবে, অনেক স্ক্রিপ্ট নিম্নলিখিত পরিস্থিতিতে AND এর আচরণ ব্যবহার করে: বলুন আপনি যদি প্রগ 1 ঠিক হয়ে যায় তবে প্রগ 2 চালাতে চান (যা ব্যাশে 0 রয়েছে)। যদি একটি বিবৃতি ( if [ prog1 ]; then; prog2; fi) না করে আপনি কেবল লিখতে পারেন ( prog1 && prog2), এবং প্রগ 2 কেবল তখনই চালিত হবে যদি প্রগ 1 এর রিটার্ন মানটি সত্য হয়।
IanC

ঠিক আছে, এই সমস্ত দুর্দান্ত পয়েন্ট। আমি &&কল করতে apt-get update && apt-get upgradeএবং &লাইনের শেষে ব্যাকগ্রাউন্ডে চালানোর জন্য ব্যবহার করি তবে এটি দুর্দান্ত পয়েন্ট যে তারা একসঙ্গে কাজ করবে না। একটি সেমিকোলন এম্পারস্যান্ডের সাথেও কাজ করে না।
জেএফএ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.