পাইপগুলি লিনাক্সে কীভাবে কাজ করে


25

লিনাক্স কার্নেলে কীভাবে পাইপগুলি প্রয়োগ করা হয় এবং আমার বোঝার বিষয়টি যাচাই করতে চেয়েছিলাম সে সম্পর্কে আমি পড়ছি। আমি যদি ভুল হয় তবে সঠিক ব্যাখ্যা সহ উত্তরটি নির্বাচন করা হবে।

  • লিনাক্সের একটি ভিএফএস রয়েছে পাইপফেস যা কার্নেলে মাউন্ট করা থাকে (ব্যবহারকারীর জায়গায় নয়)
  • পাইপফেসগুলির একটি একক সুপার ব্লক রয়েছে এবং pipe:পাশাপাশি এটির নিজস্ব রুট ( ) এ মাউন্ট করা হয়/
  • পাইপফেসগুলি বেশিরভাগ ফাইল সিস্টেমের বিপরীতে সরাসরি দেখা যায় না
  • Pipefs যাওয়ার প্রবেশ মারফত pipe(2)প্রাপ্ত syscall
  • pipe(2)সঙ্গে বংশীধ্বনিতুল্য জন্য শেল দ্বারা ব্যবহৃত প্রাপ্ত syscall |(যে কোন অন্যান্য প্রক্রিয়া থেকে হস্তচালিত বা) অপারেটর যা প্রায় কাছাকাছি সাধারন ফাইল মত আচরণ pipefs একটি নতুন ফাইল তৈরি করে
  • পাইপ অপারেটরের বাম পাশের stdoutফাইলটি পাইপফেসগুলিতে তৈরি অস্থায়ী ফাইলটিতে পুনঃনির্দেশিত করেছে
  • পাইপ অপারেটরের ডানদিকে stdinথাকা ফাইলটি পাইপফায়সে সেট করে
  • পাইপফেসগুলি মেমোরিতে এবং কিছু কার্নেল যাদু দ্বারা সংরক্ষিত থাকে, পেজ করা উচিত নয়

পাইপ (উদাহরণস্বরূপ ls -la | less) কীভাবে কার্যকর হয় তার এই ব্যাখ্যাটি কি খুব সঠিক?

একটি জিনিস যা আমি বুঝতে পারি না তা হ'ল বাশের মতো কিছু কীভাবে একটি প্রক্রিয়া সেট করে ' stdinবা stdoutফাইল বিবরণীর মাধ্যমে ফিরে আসে pipe(2)। আমি এখনও এটি সম্পর্কে কিছুই সন্ধান করতে পারিনি।


মনে রাখবেন যে আপনি একই নামের দুটি ভিন্ন ভিন্ন স্তরের বিষয়ে কথা বলছেন। pipe()যন্ত্রপাতি যে সমর্থন করে (সহ কার্নেল কল pipefs, ইত্যাদি) তুলনায় অনেক কম স্তর |অপারেটরকে আপনার শেল দেওয়া। পরেরটি সাধারণত প্রবীণ ব্যবহার করে প্রয়োগ করা হয়, তবে তা হওয়ার দরকার নেই।
গ্রেগ হিউগিল

হ্যাঁ, আমি বিশেষত নিম্ন স্তরের ক্রিয়াকলাপগুলি উল্লেখ করছি, এই ধারনা সহ যে |অপারেটর কেবল বাশের pipe(2)মতো একটি প্রক্রিয়া হিসাবে কল করছে ।
ব্র্যান্ডন ওয়াম্বল্ট

উত্তর:


19

আপনার এখনও পর্যন্ত বিশ্লেষণটি সাধারণত সঠিক। কোনও শেল কোনও প্রক্রিয়াটির স্টিডিনকে পাইপের বিবরণীতে সেট করতে পারে তা হতে পারে (সিউডোকোড):

pipe(p) // create a new pipe with two handles p[0] and p[1]
fork() // spawn a child process
    close(p[0]) // close the write end of the pipe in the child
    dup2(p[1], 0) // duplicate the pipe descriptor on top of fd 0 (stdin)
    close(p[1]) // close the other pipe descriptor
    exec() // run a new process with the new descriptors in place

ধন্যবাদ! dup2কলটি কেন প্রয়োজন তা কেবল কৌতূহলী , এবং আপনি স্টিডিনকে কেবল পাইপ বর্ণনাকারী নির্ধারণ করতে পারবেন না?
ব্র্যান্ডন ওয়াম্বল্ট

3
ফোন বর্ণনাকারীটি তৈরি করা হয় তখন ফোন বর্ণনাকারীর সংখ্যাসূচক মানটি কী তা চয়ন করতে পারে না pipe()dup2()কল আহ্বানকারী একটি নির্দিষ্ট সাংখ্যিক মান (প্রয়োজন কারণ 0, 1, 2 stdin হয়, stdout- এ, দ্বারা stderr) থেকে ফাইল বর্ণনাকারী কপি করতে পারবেন। এটি হ'ল "স্ট্যান্ডিনে সরাসরি বরাদ্দ করা" এর কার্নেলের সমতুল্য। নোট করুন যে সি রানটাইম লাইব্রেরি গ্লোবাল ভেরিয়েবল stdinএকটি FILE *, যা কার্নেল সম্পর্কিত নয় (যদিও এটি বর্ণনাকারী 0 এর সাথে সংযুক্ত হওয়ার সূচনা করা হয়েছে)।
গ্রেগ হিউগিল

দুর্দান্ত উত্তর! আমি বিশদে কিছুটা হারিয়ে গেছি। শুধু ভাবছেন আপনি এক্সিকিউটিউট চালানোর আগে (পি [1]) কেন বন্ধ করবেন? একবার dup2 ফিরে আসে, পি [1] fd 0 থেকে পয়েন্ট হবে না? তারপরে (পি [১]) ফাইল বর্ণনাকারী বন্ধ করে 0.। তারপর আমরা শিশু প্রক্রিয়াটির স্টিডিন থেকে কীভাবে পড়তে পারি?
ব্যবহারকারী 1559897

@ ব্যবহারকারী 1559897: dup2কলটি পরিবর্তন হয় না p[1]। পরিবর্তে, এটি দুটি হ্যান্ডলগুলি তৈরি করে p[1]এবং 0একই কার্নেল বস্তু (পাইপ) এ নির্দেশ করে। যেহেতু শিশু প্রক্রিয়াটির জন্য দুটি স্টিডিন হ্যান্ডেলের প্রয়োজন নেই (এবং এটি যে নাম্বার হ্যান্ডেলটি p[1]তা যাই হোক না কেন জানি না), এর p[1]আগে বন্ধ হয়ে যায় exec
গ্রেগ হিউগিল 16

@ গ্রেগ হিউগিল গটচু ধন্যবাদ!
ব্যবহারকারী 1559897
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.