টিএল; ডিআর : কারণ এটি নতুন প্রক্রিয়া তৈরি এবং ইন্টারেক্টিভ শেলটিতে নিয়ন্ত্রণ রক্ষার জন্য সর্বোত্তম পদ্ধতি
প্রক্রিয়া এবং পাইপগুলির জন্য কাঁটাচামচ () প্রয়োজনীয়
এই প্রশ্নের নির্দিষ্ট অংশের উত্তর দেওয়ার জন্য, যদি সরাসরি পিতামাতার grep blabla foo
মাধ্যমে ডাকা exec()
হত, পিতামাতার উপস্থিতি দখল করা হত, এবং সমস্ত সংস্থান সহ এর পিআইডি দখল করা হবে grep blabla foo
।
যাইহোক, আসুন exec()
এবং সম্পর্কে সাধারণভাবে কথা বলা যাক fork()
। এই জাতীয় আচরণের মূল কারণ fork()/exec()
হ'ল ইউনিক্স / লিনাক্সে একটি নতুন প্রক্রিয়া তৈরি করার মানক পদ্ধতি এবং এটি কোনও বাশ নির্দিষ্ট জিনিস নয়; এই পদ্ধতিটি শুরু থেকেই কার্যকর ছিল এবং সেই সময়ের বিদ্যমান অপারেটিং সিস্টেমগুলি থেকে এই একই পদ্ধতি দ্বারা প্রভাবিত হয়েছিল। কিছুটা সম্পর্কিত প্রশ্নে স্বর্ণিলোকের উত্তরটিরfork()
জন্য , নতুন প্রক্রিয়া তৈরি করা সহজ, যেহেতু কার্নেলের কাছে যতগুলি সম্পদ বরাদ্দ করা যায় তত কম কাজ করা যায়, এবং প্রচুর বৈশিষ্ট্য (যেমন ফাইল বর্ণনাকারী, পরিবেশ ইত্যাদি) - সমস্ত কিছু করতে পারে পিতামাতা প্রক্রিয়া থেকে উত্তরাধিকার সূত্রে প্রাপ্ত (এই ক্ষেত্রে থেকে bash
)।
দ্বিতীয়ত, ইন্টারেক্টিভ শেলগুলি যতদূর যায়, আপনি কাঁটাচামচা ছাড়া কোনও বাহ্যিক কমান্ড চালাতে পারবেন না। ডিস্কে বাস করে এমন একটি এক্সিকিউটেবল চালু করতে (উদাহরণস্বরূপ /bin/df -h
), আপনাকে কোনও exec()
পারিবারিক ফাংশন কল করতে execve()
হবে, যেমন , যা প্যারেন্টকে নতুন প্রক্রিয়াতে প্রতিস্থাপন করবে, এর পিআইডি এবং বিদ্যমান ফাইল বর্ণনাকারী ইত্যাদি গ্রহণ করবে। ইন্টারেক্টিভ শেলের জন্য, আপনি নিয়ন্ত্রণটি ব্যবহারকারীর কাছে ফিরে আসতে চান এবং পিতামাতাকে ইন্টারেক্টিভ শেল চালিয়ে যেতে দিন। সুতরাং, সবচেয়ে ভালো উপায় মাধ্যমে একটি subprocess তৈরি করা fork()
, এবং যে প্রক্রিয়া মাধ্যমে অধিগৃহীত করা যাক execve()
। সুতরাং ইন্টারেক্টিভ শেল পিআইডি 1156 fork()
পিআইডি 1157 এর মাধ্যমে কোনও শিশুকে স্পোন করবে , তারপরে কল করবে execve("/bin/df",["df","-h"],&environment)
যা /bin/df -h
পিআইডি 1157 দিয়ে রান করে। এখন শেলটি কেবল প্রসেসের বাইরে বেরিয়ে আসার জন্য অপেক্ষা করতে হবে এবং এতে নিয়ন্ত্রণ ফিরে আসতে পারে।
আপনি যেখানে দুটি বা ততোধিক কমান্ডের মধ্যে একটি পাইপ তৈরি df | grep
করতে হবে , সেখানে বলুন , আপনার দুটি ফাইল বর্ণনাকারী তৈরি করার একটি উপায় প্রয়োজন (এটি pipe()
সাইকাল থেকে আসা পাইপের শেষ অংশ পড়া এবং লেখার জন্য ), তবে কোনওভাবে দুটি নতুন প্রক্রিয়া তাদের উত্তরাধিকার সূত্রে আসুক। এটি নতুন প্রক্রিয়াটি কাঁটাচামচ করা এবং তারপরে পাইপটির লেখার প্রান্তটি dup2()
তার stdout
উফ এফডি 1 এ কল করে অনুলিপি করে (সুতরাং লেখার শেষটি এফডি 4 হয়, তবে আমরা করি dup2(4,1)
)। যখন exec()
স্পোন df
হয় তখন শিশু প্রক্রিয়াটি তার কিছুই ভাববে না stdout
এবং সচেতন না হয়ে এটিকে লিখবে (যদি না এটি সক্রিয়ভাবে পরীক্ষা করে থাকে) যে তার আউটপুটটি আসলে পাইপ হয়ে যায়। একই প্রক্রিয়া ঘটবে grep
, আমরা ছাড়া fork()
, FD 3 এবং পাইপের পঠিত শেষ নেওয়া dup(3,0)
ডিম ছাড়ার আগে grep
সঙ্গেexec()
। এই সমস্ত সময় পিতামাতার প্রক্রিয়া এখনও আছে, একবার পাইপলাইন শেষ হয়ে গেলে আবার নিয়ন্ত্রণ ফিরে পাওয়ার অপেক্ষায়।
এর বিল্ট-ইন কমান্ড, সাধারণত শেল যদি না fork()
বাদ দিয়ে, source
কমান্ড। সাবসেলের প্রয়োজন fork()
।
সংক্ষেপে, এটি একটি প্রয়োজনীয় এবং দরকারী প্রক্রিয়া।
কাঁটাচামচ করা এবং অনুকূলিতকরণের অসুবিধা ages
এখন, এই হল নন-ইন্টারেক্টিভ শেল জন্য বিভিন্ন যেমন bash -c '<simple command>'
। fork()/exec()
সর্বোত্তম পদ্ধতি হওয়া সত্ত্বেও যেখানে আপনাকে অনেকগুলি কমান্ড প্রক্রিয়াকরণ করতে হয়, এটি যখন আপনার কেবলমাত্র একটি একক কমান্ড থাকে তখন এটি সম্পদের অপচয় হয়। এই পোস্ট থেকে স্টাফেন চেজেলাসের উদ্ধৃতি দিতে :
কাঁটাচামচ ব্যয়বহুল, সিপিইউ সময়ে, মেমোরি, বরাদ্দকৃত ফাইল বর্ণনাকারী ... শেল প্রক্রিয়াটি প্রস্থান করার আগে অন্য প্রক্রিয়াটির জন্য অপেক্ষা করা সম্পর্কে থাকা কেবল সম্পদের অপচয় is এছাড়াও, পৃথক প্রক্রিয়া থেকে প্রস্থান স্থিতি সঠিকভাবে রিপোর্ট করা শক্ত হয়ে তোলে যা কমান্ডটি কার্যকর করে (উদাহরণস্বরূপ, প্রক্রিয়াটি মারা গেলে)।
অতএব, অনেকগুলি শেল (কেবল নয় bash
) সেই একক সাধারণ কমান্ড দ্বারা এটি নিয়ন্ত্রণ exec()
করার অনুমতি দেয় bash -c ''
। এবং ঠিক উপরে বর্ণিত কারণগুলির জন্য, শেল স্ক্রিপ্টগুলিতে পাইপলাইনগুলি হ্রাস করা আরও ভাল। প্রায়শই আপনি দেখতে পারা যায় নবজাতকরা এরকম কিছু করেন:
cat /etc/passwd | cut -d ':' -f 6 | grep '/home'
অবশ্যই, এটি fork()
3 প্রক্রিয়া করবে । এটি একটি সাধারণ উদাহরণ, তবে গিগাবাইটের পরিসীমাতে একটি বৃহত ফাইল বিবেচনা করুন। এটি একটি প্রক্রিয়ার সাথে আরও দক্ষ হতে চাই:
awk -F':' '$6~"/home"{print $6}' /etc/passwd
সংস্থানগুলির বর্জ্য আসলে পরিষেবা অস্বীকারের এক রূপ হতে পারে এবং বিশেষত কাঁটাচামচ বোমাগুলি শেল ফাংশনগুলির মাধ্যমে তৈরি করা হয় যা তাদের পাইপলাইনে কল করে, যা নিজের একাধিক অনুলিপি কাঁটাচ্ছে। আজকাল, সিস্টেমেডে সিগ্রুপগুলিতে সর্বাধিক সংখ্যক প্রক্রিয়া সীমাবদ্ধ করে এটি প্রশমিত করা হয় , যা উবুন্টু 15.04 সংস্করণ থেকেও ব্যবহার করে।
অবশ্যই এর অর্থ এই নয় যে কাঁটাচামচ করা কেবল খারাপ। এটি এখনও আগে যেমন আলোচিত একটি কার্যকর প্রক্রিয়া, তবে আপনি যেখানে কম প্রক্রিয়া, এবং ক্রমাগত কম সংস্থান এবং আরও ভাল পারফরম্যান্স নিয়ে দূরে সরে যেতে fork()
পারেন সেখানে যদি সম্ভব হয় তবে আপনার এড়ানো উচিত ।
আরো দেখুন