নামযুক্ত পাইপ, ফাইল বর্ণনাকারী এবং ইওএফ


10

দুটি উইন্ডো, একই ব্যবহারকারী, বাশ প্রম্পট সহ। উইন্ডো -১ প্রকারে:

$ mkfifo f; exec <f

সুতরাং বাশ এখন ফাইল বর্ণনাকারী 0 থেকে পড়ার চেষ্টা করছে, যা নামযুক্ত পাইপে ম্যাপ করা হয়েছে f। উইন্ডো -2 টাইপ করুন:

$ echo ls > f

এখন উইন্ডো -1 একটি এলএস প্রিন্ট করে এবং তখন শেলটি মারা যায়। কেন?

পরবর্তী পরীক্ষা: উইন্ডো -১ টি আবার খুলুন exec <f। উইন্ডো -2 টাইপ করুন:

$ exec 3>f
$ echo ls >&3

উপরের প্রথম লাইনের পরে, উইন্ডো -1 উঠে এবং একটি প্রম্পট মুদ্রণ করবে। কেন? উপরের দ্বিতীয় লাইনের পরে, উইন্ডো -1 lsআউটপুট মুদ্রণ করে এবং শেলটি জীবিত থাকে। কেন? আসলে, এখন উইন্ডো -2 এ, echo ls > fউইন্ডো -1 শেলটি বন্ধ করে না।

উত্তরটি অবশ্যই উইন্ডো -2 থেকে ফাইলের বর্ণনাকারী 3 এর অস্তিত্বের সাথে নামযুক্ত পাইপটি উল্লেখ করতে হবে ?!


1
পরে exec <f, bashপ্রয়াস নয় পড়া থেকে f, এটা প্রথম প্রয়াস করছে খুলতে করুন। open()কিছু পাইপ থেকে লেখার মোডে অন্য খোলা (যা এ নির্দেশ নল instantiated করা হবে, এবং শেল তা থেকে ইনপুট পড়তে হবে) করছেন প্রক্রিয়া আছে না হওয়া অবধি ফিরবে করা হবে না।
স্টাফেন চেজেলাস

দুর্দান্ত পয়েন্ট, @ স্টাফেনচেজেলাস। এ কারণেই অবশ্যই একবার exec 3>fচালানো হলে প্রথম শেলটি একটি প্রম্পট দেয়। (মাইনর পয়েন্ট, আপনার মন্তব্যে কি " লিখিত মোডে"
বোঝানো হয়েছে

1
অস্ত্রোপচার. 5 মিনিটের সময়সীমার ঠিক আগে এখন সম্পাদিত
স্টাফেন চ্যাজেলাস

উত্তর:


12

ফাইল ডেস্ক্রিপ্টর বন্ধ করার সাথে এটি করা দরকার ।

আপনার প্রথম উদাহরণে, echoএটির স্ট্যান্ডার্ড আউটপুট প্রবাহে লিখুন যা শেলটি এর সাথে সংযোগ স্থাপনের জন্য খোলে fএবং যখন এটি বন্ধ হয়, তখন এর বিবরণীটি বন্ধ হয় (শেল দ্বারা)। প্রাপ্তির শেষে, শেলটি, যা এর স্ট্যান্ডার্ড ইনপুট স্ট্রিমের সাথে ইনপুট fপড়ে (সংযুক্ত ) পড়ে ls, চালিত হয় lsএবং তার স্ট্যান্ডার্ড ইনপুট-এ ফাইলের শেষের কারণে শেষ হয়।

ফাইলের শেষের অবস্থাটি দেখা দেয় কারণ নামকৃত পাইপের সমস্ত লেখক (এই উদাহরণে কেবলমাত্র একজন) পাইপের শেষ প্রান্তটি বন্ধ করে দিয়েছেন।

আপনার দ্বিতীয় উদাহরণে, exec 3>fলিখিতভাবে জন্য ফাইল বর্ণনাকারী 3 প্রর্দশিত f, তারপর echoলিখেছেন lsএটি। এটি শেলটির সাথে এখন ফাইল বর্ণনাকারী খোলা আছে, echoকমান্ডটি নয়। বর্ণনাকারী আপনি না করা পর্যন্ত খোলা থাকে exec 3>&-। প্রাপ্তির শেষে, শেলটি, যা তার স্ট্যান্ডার্ড ইনপুট স্ট্রিমের সাথে ইনপুট fপড়ে (সংযুক্ত ) পড়ে ls, চালিত হয় lsএবং তারপরে আরও ইনপুটটির জন্য অপেক্ষা করে (যেহেতু স্ট্রিমটি এখনও উন্মুক্ত)।

প্রবাহ দেহাবশেষ খুলতে কারণ এটি সব লেখকদের (শেল মাধ্যমে exec 3>f, এবং echo) আছে না পাইপের তাদের শেষ বন্ধ ( exec 3>fএখনও পর্যন্ত যায়)।


আমি echoউপরে লিখেছি যেন এটি বাহ্যিক আদেশ। এটি সম্ভবত শেল মধ্যে নির্মিত হয়। তবুও প্রভাব একই।


6

এটির তেমন কিছুই নেই: যখন পাইপে কোনও লেখক নেই, তখন এটি পাঠকদের কাছে বন্ধ মনে হয়, অর্থাত্ পড়ার সময় ইওএফ ফেরত দেয় এবং খোলার সময় ব্লক করে।

লিনাক্স ম্যান পৃষ্ঠা থেকে ( pipe(7)তবে আরও দেখুন fifo(7)):

যদি কোনও পাইপের লেখার প্রান্তটি উল্লেখ করে সমস্ত ফাইল বর্ণনাকারী বন্ধ করে দেওয়া হয়, তবে read(2)পাইপটি থেকে চেষ্টা করার পরে ফাইলটি শেষের দিকে ( read(2)0 ফিরে আসবে) দেখতে পাবে।

লেখার শেষটি বন্ধ করে দেওয়াটাই হ'ল প্রান্তের শেষে স্পষ্টভাবে ঘটে echo ls >fএবং আপনি যেমনটি বলেন, অন্য ক্ষেত্রে ফাইল বিবরণকারীটি খোলা রাখা হয়।


জাভাতে (এবং অন্যান্য OO ভাষাগুলি) রেফারেন্স গণনাগুলিতে এক ধরণের উপমা মনে হয়! যদিও বোধগম্য হয়।
ফিক্সি

2

@ কুসালানন্দ এবং @ কিকছু থেকে দুটি উত্তর পড়ার পরে, আমি মনে করি আমি বুঝতে পেরেছি। উইন্ডো -১ এ, শেলটি পাইপের লেখার প্রান্তটি দুটি খুলতে এবং তারপরে এটি বন্ধ করার জন্য কিছু অপেক্ষা করছে। লেখার শেষটি খোলার পরে, উইন্ডো -১ এর শেল একটি প্রম্পট প্রিন্ট করে। লেখার শেষ বন্ধ হয়ে গেলে শেলটি ইওএফ পায় এবং মারা যায়।

প্রথম অবস্থায়: জানালা-2 দিকে আমরা দুই পরিস্থিতিতে আমার প্রশ্ন বর্ণিত আছে echo ls > f, কোন ফাইল বর্ণনাকারী 3, আছে তাই আমরা আছে echoডিম ছাড়ার এবং তার stdinএবং stdoutভালো চেহারা:

0 --> tty
1 --> f

তারপরে echoসমাপ্ত হয় এবং শেল দুটি বর্ণনাকারী বন্ধ করে দেয়। যেহেতু ফাইল বর্ণনাকারী 1 বন্ধ রয়েছে এবং রেফারেন্স রয়েছে f, তাই লেখার fশেষটি বন্ধ হয়ে যায় এবং এটি ইওএফ-এর উইন্ডো -1 এ নিয়ে যায়।

দ্বিতীয় পরিস্থিতিতে, আমরা exec 3>fআমাদের শেলটি চালাই , যার ফলে শেলটি এই পরিবেশটি গ্রহণ করে:

bash:
0 --> tty
1 --> tty
2 --> tty
3 --> f

এখন আমরা চালাই echo ls >& 3এবং শেল echoনিম্নলিখিত বর্ণনার জন্য ফাইল বর্ণনাকারী বরাদ্দ করে:

echo:
0 --> tty
1 --> f     # because 3 points to f
2 --> tty

তারপর শেল সহ উপরে, তিন বর্ণনাকারী বন্ধ f, কিন্তু fএখনও শেল নিজেই থেকে এটা একটি রেফারেন্স আছে। এটি গুরুত্বপূর্ণ পার্থক্য। বর্ণনাকারী ৩ টি exec 3>&-বন্ধ করে শেষ খোলা রেফারেন্সটি বন্ধ হবে এবং উইন্ডো -১ এ কোনও ইওএফ তৈরি করবে, যেমন @ কুসালানন্দ উল্লেখ করেছেন।


এটি পরিবর্তন করার উপযুক্ত ডিজাইনের কারণ না থাকলে প্রথম তিনটি ফাইল বর্ণনাকারীকে কেন আপনার একা রাখা উচিত, এটির এটি একটি উত্তম উদাহরণ। যখন আপনি ডেস্ক্রিপ্টর (1) ব্যবহার করেছিলেন যা অন্য শেলের সাথে ইনপুট ডেস্ক্রিপ্টর (0) হিসাবে শেষ হয়েছিল, আপনি কেবল পাইপটি বন্ধ করেন নি (এবং আপনি সেই নির্দিষ্ট ডেটা স্ট্রিমের সাথে কী করছেন), তবে দ্বিতীয়টিতে ইনপুটটি বন্ধ করে দিয়েছেন শেল যার ফলে এটি শেষ হয়ে যায়। এটি ঠিক আছে, তবে কেবল যদি আপনি এটি উদ্দেশ্য করে করছেন। উচ্চতর সংখ্যাযুক্ত ফাইল বর্ণনাকারী ব্যবহার করে এর মতো পার্শ্ব প্রতিক্রিয়া এড়ানো যায় কারণ কোনও কিছুই এগুলি কোনও বিশেষ অবস্থায় বা এমনকি সংজ্ঞায়িত হওয়ার আশা করে না।
জো

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