দ্রষ্টব্য: উত্তরটি এই সাইটে এবং ইউনিক্স.স্ট্যাকেক্সেঞ্জ.কম.- এ সমবয়সীদের দ্বারা উত্তরগুলি গবেষণা এবং পড়া সম্পর্কে জড়িত, এই মেকানিজমগুলি সম্পর্কে আমার নিজস্ব বোঝার প্রতিফলন করে এবং সময় চলার সাথে সাথে আপডেট করা হবে। প্রশ্ন জিজ্ঞাসা করতে বা মন্তব্যগুলির উন্নতির পরামর্শ দিতে দ্বিধা করবেন না। সিস্কলগুলি strace
কমান্ড সহ শেলটিতে কীভাবে কাজ করে তা দেখার চেষ্টা করার পরামর্শ দিই suggest এছাড়াও দয়া করে ইন্টার্নাল বা সিস্কলগুলির ধারণা থেকে ভয় পান না - শেল কীভাবে কাজ করে তা বোঝার জন্য আপনাকে সেগুলি জানতে বা ব্যবহার করতে সক্ষম হবে না তবে তারা অবশ্যই বুঝতে সহায়তা করে।
টি এল; ডিআর
|
পাইপগুলি ডিস্কে প্রবেশের সাথে সম্পর্কিত নয়, সুতরাং ডিস্ক ফাইল সিস্টেমের একটি ইনোড সংখ্যা নেই (তবে কার্নেল-স্পেসে পাইপফেস ভার্চুয়াল ফাইল সিস্টেমের ইনোড রয়েছে ), তবে পুনঃনির্দেশগুলি প্রায়শই ফাইলগুলিতে জড়িত থাকে, যার সাথে ডিস্ক এন্ট্রি থাকে এবং যার ফলে সংশ্লিষ্ট হয় inode।
- পাইপগুলি
lseek()
সক্ষম হয় না যাতে কমান্ডগুলি কিছু ডেটা পড়তে না পারে এবং তারপরে পুনরায় রিওয়াইন্ড করতে পারে, তবে আপনি যখন পুনঃনির্দেশ করেন >
বা <
সাধারণত এটি এমন কোনও ফাইল যা lseek()
সক্ষম অবজেক্ট, সুতরাং কমান্ডগুলি তারা খুশি তবে নেভিগেট করতে পারে।
- পুনর্নির্দেশগুলি হ'ল ফাইল বর্ণনাকারীদের ম্যানিপুলেশনস, যা অনেকগুলি হতে পারে; পাইপগুলিতে দুটি ফাইল বর্ণনাকারী রয়েছে - একটি বাম কমান্ডের জন্য এবং একটি ডান কমান্ডের জন্য
- স্ট্যান্ডার্ড স্ট্রিম এবং পাইপগুলিতে পুনঃনির্দেশ উভয়টি বাফার করা।
- পাইপ প্রায় সর্বদা কাঁটা জড়িত এবং তাই প্রক্রিয়া জোড়া যুক্ত; পুনর্নির্দেশগুলি - সর্বদা নয়, যদিও উভয় ক্ষেত্রেই ফলস্বরূপ ফাইল বর্ণনকারীগুলি উপ-প্রক্রিয়াগুলির দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত হয়।
- পাইপ সবসময় ফাইল বর্ণনাকারী সংযুক্ত করে (একটি জুড়ি), পুনর্নির্দেশগুলি - হয় কোনও পথনাম বা ফাইল বর্ণনাকারী ব্যবহার করে।
- পাইপগুলি হ'ল আন্ত-প্রক্রিয়া যোগাযোগ পদ্ধতি, অন্যদিকে পুনর্নির্দেশগুলি কেবল খোলা ফাইল বা ফাইল-জাতীয় বস্তুগুলিতে ম্যানিপুলেশন
- দু'জনেই
dup2()
ফাইল বর্ণনাকারীর অনুলিপি সরবরাহ করার জন্য হুডের নীচে সিস্টস্কল নিয়োগ করেন , যেখানে প্রকৃত তথ্যের প্রবাহ ঘটে।
- পুনর্নির্দেশগুলি
exec
বিল্ট-ইন কমান্ডের সাথে "বিশ্বব্যাপী" প্রয়োগ করা যেতে পারে ( এটি এবং এটি দেখুন ), সুতরাং আপনি যদি exec > output.txt
প্রতিটি আদেশ করেন output.txt
তবে তা থেকে লিখতে হবে । |
পাইপগুলি কেবল বর্তমান কমান্ডের জন্য প্রয়োগ করা হয় (যার অর্থ সরল কমান্ড বা সাবশেলের মতো seq 5 | (head -n1; head -n2)
বা যৌগিক কমান্ড)।
যখন ফেরৎ ফাইল সম্পন্ন হলে, ভালো জিনিস echo "TEST" > file
এবং echo "TEST" >> file
উভয় ব্যবহার open()
এটি ফাইলের প্রাপ্ত syscall ( তাও দেখতে ) এবং এটি পাস করার তা থেকে ফাইল বর্ণনাকারী পেতে dup2()
। পাইপগুলি |
কেবল ব্যবহার pipe()
এবং dup2()
সিস্কেল।
যতক্ষণ না কমান্ড কার্যকর করা হচ্ছে, পাইপ এবং পুনঃনির্দেশ ফাইল ফাইল বর্ণনাকারী - ফাইল-জাতীয় বস্তু ছাড়া আর কিছু নয় যা তারা অন্ধভাবে লিখতে পারে বা তাদের অভ্যন্তরীণভাবে ম্যানিপুলেট করে (যা অপ্রত্যাশিত আচরণ তৈরি করতে পারে; apt
উদাহরণস্বরূপ, এমনকি স্টাডাউটকেও লেখেন না যদি এটি জানে যে পুনঃনির্দেশ আছে)।
ভূমিকা
এই দুটি প্রক্রিয়া কীভাবে আলাদা হয় তা বোঝার জন্য তাদের প্রয়োজনীয় বৈশিষ্ট্যগুলি, দুটির পিছনের ইতিহাস এবং সি প্রোগ্রামিং ভাষায় তাদের শিকড়গুলি বোঝার প্রয়োজন। প্রকৃতপক্ষে, ফাইল বর্ণনাকারী কী এবং কীভাবে dup2()
এবং pipe()
সিস্টেম কল কাজ করে তা জেনে রাখাও প্রয়োজনীয় lseek()
। শেলটি ব্যবহারকারীর কাছে এই প্রক্রিয়াগুলি বিমূর্ত করার একটি উপায় হিসাবে বোঝানো হয়, তবে বিমূর্তির চেয়ে গভীর খনন শেলের আচরণের প্রকৃত প্রকৃতিটি বুঝতে সহায়তা করে।
পুনঃনির্দেশ এবং পাইপগুলির উত্স
ডেনিস রিচের প্রবন্ধটি ভবিষ্যদ্বাণীমূলক পেট্রোগ্লাইফস অনুসারে পাইপগুলির উৎপত্তি ম্যালকম ডগলাস ম্যাকিল্রয়ের 1964 সালের অভ্যন্তরীণ মেমো থেকে হয়েছিল , যখন তারা মাল্টিক্স অপারেটিং সিস্টেমের সাথে কাজ করছিলেন । উক্তি:
আমার শক্তিশালী উদ্বেগকে সংক্ষেপে জানাতে:
- আমাদের বাগানের পায়ের পাতার মোজাবিশেষের মতো প্রোগ্রামগুলি সংযুক্ত করার কিছু উপায় থাকতে হবে - যখন অন্য উপায়ে ডেটা ম্যাসেজ করার প্রয়োজন হয় তখন এটি হয়ে যায় অন্য বিভাগে স্ক্রু। এটিও আইওয়ের পথ।
যা স্পষ্ট তা হ'ল সেই সময়ে প্রোগ্রামগুলি ডিস্কে লিখতে সক্ষম ছিল, তবে আউটপুট বড় হলে এটি অদক্ষ ছিল। ইউনিক্স পাইপলাইন ভিডিওতে ব্রায়ান কার্নিগানের ব্যাখ্যাটি উদ্ধৃত করতে :
প্রথমত, আপনাকে একটি বৃহত্তর বিশাল প্রোগ্রাম লিখতে হবে না - আপনার বিদ্যমান ছোট ছোট প্রোগ্রাম রয়েছে যা ইতিমধ্যে কাজের অংশগুলি করতে পারে ... অন্যটি হ'ল এটি সম্ভব যে আপনি যে পরিমাণ ডেটা প্রসেস করছেন তার পরিমাণ ফিট না হলে আপনি এটি একটি ফাইলে সংরক্ষণ করেছেন ... কারণ মনে রাখবেন, আমরা সেই দিনগুলিতে ফিরে এসেছি যখন এই জিনিসগুলির ডিস্কগুলি ছিল আপনি যদি ভাগ্যবান হন তবে কোনও মেগাবাইট বা দুটি ডেটা ... তাই পাইপলাইনটিকে কখনই পুরো আউটপুট ইনস্ট্যান্ট করতে হত না So ।
সুতরাং ধারণাগত পার্থক্য স্পষ্ট: পাইপ হ'ল প্রোগ্রামগুলি একে অপরের সাথে কথা বলার একটি প্রক্রিয়া। পুনর্নির্দেশগুলি - মৌলিক স্তরে ফাইল লেখার উপায়। উভয় ক্ষেত্রে শেল এই দুটি জিনিসকে সহজ করে তোলে তবে ফণা নীচে পুরোপুরি প্রচুর কাজ চলছে।
আরও গভীরতর হচ্ছে: শেলটির সিস্কেল এবং অভ্যন্তরীণ কাজ
আমরা ফাইল বর্ণনাকারীর ধারণা দিয়ে শুরু করি । ফাইল বর্ণনাকারীরা মূলত একটি উন্মুক্ত ফাইল (এটি ডিস্কের একটি ফাইল, বা মেমরির, বা বেনামে ফাইল) এর বর্ণনা দেয় যা কোনও পূর্ণসংখ্যার সংখ্যা দ্বারা উপস্থাপিত হয়। দুটি স্ট্যান্ডার্ড ডেটা স্ট্রিম (স্টিডিন, স্টডআউট, স্টেডার) যথাক্রমে ফাইল বর্ণনাকারী 0,1 এবং 2। ওরা কোথা থেকে আসে ? ভাল, শেল কমান্ডগুলিতে ফাইল বর্ণনাকারী তাদের পিতামাতাদের - শেল থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয়। এবং এটি সমস্ত প্রক্রিয়াগুলির জন্য সাধারণভাবে সত্য - শিশু প্রক্রিয়া পিতামাতার ফাইল বর্ণনাকারীদের উত্তরাধিকার সূত্রে পায়। ডেমনগুলির জন্য সমস্ত উত্তরাধিকার সূত্রে প্রাপ্ত ফাইল বর্ণনাকারী বন্ধ করে এবং / অথবা অন্য জায়গায় পুনর্নির্দেশ করা সাধারণ।
পুনঃনির্দেশে ফিরে যান। আসলেই কি? এটি এমন একটি প্রক্রিয়া যা শেলকে কমান্ডের জন্য ফাইল বর্ণনাকারী প্রস্তুত করতে বলে (কারণ কমান্ড চালুর আগে শেল দ্বারা পুনর্নির্দেশগুলি সম্পন্ন করা হয়), এবং ব্যবহারকারীর পরামর্শ অনুসারে সেগুলি নির্দেশ করুন। স্ট্যান্ডার্ড ডেফিনেশনে আউটপুট ফেরৎ হয়
[n]>word
যে [n]
ফাইল বর্ণনাকারী নম্বর আছে। আপনি যখন echo "Something" > /dev/null
1 নম্বরটি করেন তখন সেখানে জড়িত থাকে এবং echo 2> /dev/null
।
হুডের নীচে এটি dup2()
সিস্টেম কলের মাধ্যমে ফাইল বর্ণনাকারীর সদৃশ করে করা হয় । চলুন df > /dev/null
। শেলটি একটি শিশু প্রক্রিয়া তৈরি করবে যেখানে এটি df
চালিত হবে, তবে এর আগে এটি /dev/null
ফাইল বর্ণনাকারী # 3 হিসাবে খুলবে এবং dup2(3,1)
জারি করা হবে, যা ফাইল বিবরণকারী 3 এর একটি অনুলিপি তৈরি করে এবং অনুলিপিটি হবে 1 আপনি কীভাবে আপনার দুটি ফাইল আছে তা জানেন file1.txt
এবং file2.txt
, এবং যখন cp file1.txt file2.txt
আপনার কাছে দুটি একই ফাইল থাকবে তবে আপনি সেগুলি স্বাধীনভাবে পরিচালনা করতে পারেন? কিন্ডা এখানে একই ঘটনা ঘটছে। প্রায়শই আপনি দেখতে পারেন যে নির্বাচনে দাঁড়ানোর আগে bash
কি করতে হবে dup(1,10)
একটি কপি ফাইল বর্ণনাকারী # 1 যা করতে stdout
(এবং যে কপি FD # 10 হবে) যাতে এটা পরে পুনরুদ্ধার হবে। গুরুত্বপূর্ণ হ'ল নোট করা যখন আপনি বিল্ট-ইন কমান্ডগুলি বিবেচনা করেন(যা নিজেই শেলের অংশ, এবং কোনও /bin
বা অন্য কোথাও কোনও ফাইল নেই ) বা অ-ইন্টারেক্টিভ শেলের সাধারণ কমান্ড , শেলটি শিশু প্রক্রিয়া তৈরি করে না।
এবং তারপর আমরা ভালো জিনিস আছে [n]>&[m]
এবং [n]&<[m]
। এটি ফাইল বর্ণনাকারীর সদৃশ, যা dup2()
এখনকার শেল সিনট্যাক্সের মতো একই প্রক্রিয়াটি ব্যবহারকারীর জন্য সুবিধাজনকভাবে উপলব্ধ।
পুনঃনির্দেশ সম্পর্কে নোট করার জন্য একটি গুরুত্বপূর্ণ বিষয় হ'ল তাদের অর্ডার স্থির নয়, তবে শেল কীভাবে ব্যবহারকারী চায় তার ব্যাখ্যা কীভাবে তা গুরুত্বপূর্ণ। নিম্নলিখিত তুলনা করুন:
# Make copy of where fd 2 points , then redirect fd 2
$ ls -l /proc/self/fd/ 3>&2 2> /dev/null
total 0
lrwx------ 1 user user 64 Sep 13 00:08 0 -> /dev/pts/0
lrwx------ 1 user user 64 Sep 13 00:08 1 -> /dev/pts/0
l-wx------ 1 user user 64 Sep 13 00:08 2 -> /dev/null
lrwx------ 1 runner user 64 Sep 13 00:08 3 -> /dev/pts/0
lr-x------ 1 user user 64 Sep 13 00:08 4 -> /proc/29/fd
# redirect fd #2 first, then clone it
$ ls -l /proc/self/fd/ 2> /dev/null 3>&2
total 0
lrwx------ 1 user user 64 Sep 13 00:08 0 -> /dev/pts/0
lrwx------ 1 user user 64 Sep 13 00:08 1 -> /dev/pts/0
l-wx------ 1 user user 64 Sep 13 00:08 2 -> /dev/null
l-wx------ 1 user user 64 Sep 13 00:08 3 -> /dev/null
lr-x------ 1 user user 64 Sep 13 00:08 4 -> /proc/31/fd
শেল স্ক্রিপ্টিং এগুলির ব্যবহারিক ব্যবহার বহুমুখী হতে পারে:
এবং আরও অনেকে.
সঙ্গে নদীর গভীরতানির্ণয় pipe()
এবংdup2()
সুতরাং পাইপগুলি কীভাবে তৈরি হয়? pipe()
সিস্কেল মাধ্যমে , যা ইনপুট হিসাবে pipefd
দুটি ধরণের আইটেম int
(পূর্ণসংখ্যার) নামক একটি অ্যারে (ওরফে তালিকা) হিসাবে গ্রহণ করবে । এই দুটি পূর্ণসংখ্যা ফাইল বর্ণনাকারী। pipefd[0]
পাইপের পড়া শেষ হতে পারে এবং pipefd[1]
লেখার শেষ হবে। সুতরাং df | grep 'foo'
, এর grep
অনুলিপি পাবেন pipefd[0]
এবং এর df
একটি অনুলিপি পাবেন pipefd[1]
। কিন্তু কিভাবে ? অবশ্যই, dup2()
সিস্কেলের যাদু দিয়ে । জন্য df
আমাদের উদাহরণে, এর কথা বলা যাক pipefd[1]
# 4 আছে, তাই শেল একটি শিশু করতে, কি করতে হবে dup2(4,1)
(আমার স্মরণ cp
উদাহরণ?), এবং তারপর কি execve()
আসলে চালানোর জন্য df
। স্বাভাবিকভাবে,df
ফাইল বর্ণনাকারী # 1 উত্তরাধিকার সূত্রে প্রাপ্ত হবে, তবে এটি অজানা হবে যে এটি আর টার্মিনালটির দিকে নির্দেশ করছে না, তবে আসলে এফডি # 4, যা আসলে পাইপের লেখার শেষ end স্বাভাবিকভাবেই, grep 'foo'
ফাইল বর্ণনাকারীর বিভিন্ন সংখ্যক ব্যতীত একই জিনিসটি ঘটবে ।
এখন, আকর্ষণীয় প্রশ্ন: আমরা কী এমন পাইপগুলি তৈরি করতে পারি যা এফডি # 2 কেও পুনর্নির্দেশ করতে পারে, কেবল এফডি # 1 নয়? হ্যাঁ, বাস্তবে এটি হ'ল |&
বাশে। পসিক্স স্ট্যান্ডার্ডটির জন্য df 2>&1 | grep 'foo'
সিনট্যাক্স সমর্থন করার জন্য শেল কমান্ড ভাষা প্রয়োজন , তবে bash
এটিও করে |&
।
গুরুত্বপূর্ণ বিষয়গুলি যা গুরুত্বপূর্ণ তা হ'ল পাইপগুলি সর্বদা ফাইল বর্ণনাকারীদের সাথে ডিল করে। সেখানে বিদ্যমান FIFO
বা নামযুক্ত পাইপ রয়েছে , যার ডিস্কে একটি ফাইলের নাম রয়েছে এবং আসুন আপনি এটি ফাইল হিসাবে ব্যবহার করুন তবে পাইপের মতো আচরণ করে। তবে |
পাইপের ধরণগুলি হ'ল অজ্ঞাতনামা পাইপ হিসাবে পরিচিত - তাদের কোনও ফাইলের নাম নেই, কারণ তারা সত্যিকার অর্থে কেবল দুটি বস্তু এক সাথে সংযুক্ত। আমরা ফাইলগুলির সাথে কাজ করছি না এই বিষয়টিও একটি গুরুত্বপূর্ণ জড়িত: পাইপগুলি lseek()
সক্ষম নয়। মেমরি বা ডিস্কে থাকা ফাইলগুলি স্থিতিশীল - প্রোগ্রামগুলি lseek()
120 বাইটে লাফিয়ে সিস্কল ব্যবহার করতে পারে , তারপরে 10 বাইটে ফিরে, তারপরে শেষের দিকে এগিয়ে যেতে পারে। পাইপ স্থিতিশীল নয় - সেগুলি ক্রমযুক্ত এবং তাই আপনি তাদের কাছ থেকে প্রাপ্ত ডেটা রিওয়াইন্ড করতে পারবেন নাlseek()
। কিছু ফাইল প্রোগ্রাম থেকে যদি তারা ফাইল বা পাইপ থেকে পড়ছেন তবে এটি দক্ষতার সাথে দক্ষতার জন্য প্রয়োজনীয় সামঞ্জস্য করতে পারে; অন্য কথায়, একটি prog
যদি আমি না সনাক্ত করতে cat file.txt | prog
বা prog < input.txt
। এর বাস্তব কাজের উদাহরণ লেজ ।
পাইপগুলির অন্য দুটি অত্যন্ত আকর্ষণীয় সম্পত্তি হ'ল তাদের একটি বাফার রয়েছে, যা লিনাক্সে 4096 বাইট এবং লিনাক্স উত্স কোডে সংজ্ঞায়িত হিসাবে তাদের আসলে একটি ফাইল সিস্টেম রয়েছে ! এগুলি চারপাশের ডেটা পাস করার জন্য কেবল কোনও বস্তু নয়, তারা নিজেরাই একটি ডেটাস্ট্রাকচার! বাস্তবে পাইপস ফাইল সিস্টেম বিদ্যমান রয়েছে, যা পাইপ এবং এফআইএফও উভয়ই পরিচালনা করে, পাইপগুলির নিজ নিজ ফাইল সিস্টেমে একটি ইনোড নম্বর থাকে:
# Stdout of ls is wired to pipe
$ ls -l /proc/self/fd/ | cat
lrwx------ 1 user user 64 Sep 13 00:02 0 -> /dev/pts/0
l-wx------ 1 user user 64 Sep 13 00:02 1 -> pipe:[15655630]
lrwx------ 1 user user 64 Sep 13 00:02 2 -> /dev/pts/0
lr-x------ 1 user user 64 Sep 13 00:02 3 -> /proc/22/fd
# stdin of ls is wired to pipe
$ true | ls -l /proc/self/fd/0
lr-x------ 1 user user 64 Sep 13 03:58 /proc/self/fd/0 -> 'pipe:[54741]'
লিনাক্স পাইপগুলি পুনঃনির্দেশের মতোই ইউনি-দিকনির্দেশক। কিছু ইউনিক্স-এর মতো বাস্তবায়নের ক্ষেত্রে - দ্বি-দিকনির্দেশক পাইপ রয়েছে। যদিও শেল স্ক্রিপ্টিংয়ের যাদু দিয়ে, আপনি লিনাক্সে দ্বি-দিকনির্দেশক পাইপও তৈরি করতে পারেন ।
আরো দেখুন:
thing1 > temp_file && thing2 < temp_file
পাইপগুলির সাহায্যে আরও সহজ করার কথা উল্লেখ করেছেন। তবে কেন>
অপারেটরটিকে এটি করতে পুনরায় ব্যবহার করবেন না, যেমনthing1 > thing2
কমান্ডের জন্যthing1
এবংthing2
? অতিরিক্ত অপারেটর কেন|
?