আপনি ইতিমধ্যে কয়েকটি খুব ভাল উত্তর পেয়েছেন। আমাকে জোর দেওয়া যাক যদিও এখানে দুটি পৃথক ধারণা জড়িত রয়েছে, যার বোঝা বিপুলভাবে সহায়তা করে:
পটভূমি: ফাইল বর্ণনাকারী বনাম ফাইল সারণী
আপনার ফাইল বর্ণনাকারী কেবল 0 ... এন, যা আপনার প্রক্রিয়াতে ফাইল বর্ণনাকারী সারণীতে সূচক। কনভেনশন অনুসারে, STDIN = 0, STDOUT = 1, STDERR = 2 (দ্রষ্টব্য যে এখানে শর্তাদি STDIN
কিছু প্রোগ্রামিং ভাষা এবং ম্যান পৃষ্ঠাতে কনভেনশন দ্বারা ব্যবহৃত প্রতীক / ম্যাক্রোগুলি, এখানে STDIN নামে একটি আসল "অবজেক্ট" নেই; এই আলোচনার উদ্দেশ্য, stdin হল 0, ইত্যাদি)।
এই ফাইল বর্ণনাকারী টেবিলটিতে প্রকৃত ফাইলটি সম্পর্কে কোনও তথ্য নেই। পরিবর্তে, এটিতে একটি পৃথক ফাইল টেবিলের পয়েন্টার রয়েছে; পরবর্তীকালে একটি প্রকৃত শারীরিক ফাইল (বা ব্লক ডিভাইস, বা পাইপ, বা লিনাক্স ফাইল মেকানিজমের মাধ্যমে সম্বোধন করতে পারে) এবং আরও তথ্য (যেমন এটি পড়া বা লেখার জন্য কিনা) সম্পর্কিত তথ্য রয়েছে।
সুতরাং আপনি যখন ব্যবহার করেন >
বা <
আপনার শেল ব্যবহার করেন , তখন আপনি কেবল অন্য কোনও দিকে নির্দেশ করতে সংশ্লিষ্ট ফাইল বর্ণনাকারীর পয়েন্টারটি প্রতিস্থাপন করেন। বাক্য গঠনটি 2>&1
কেবল বর্ণনাকারী 2 কে যেখানে 1 পয়েন্টে নির্দেশ করে। > file.txt
কেবল file.txt
লেখার জন্য খোলে এবং স্টডআউট (ফাইল ডিক্স্রিপ্টর 1) এটিতে নির্দেশ করে।
অন্যান্য গুডিও রয়েছে, যেমন 2>(xxx)
(যেমন: একটি নতুন প্রক্রিয়া চলমান xxx
তৈরি করুন, একটি পাইপ তৈরি করুন, নতুন প্রক্রিয়াটির ফাইল বর্ণনাকারী 0 টি পাইপের পড়ার শেষের সাথে সংযুক্ত করুন এবং মূল প্রক্রিয়াটির 2 বর্ণনাকারী ফাইলটি লেখার শেষের সাথে সংযুক্ত করুন পাইপ)।
এটি আপনার শেল ছাড়াও অন্যান্য সফ্টওয়্যারের "ফাইল হ্যান্ডেল যাদু" এর ভিত্তি। উদাহরণস্বরূপ, আপনি, পার্ল স্ক্রিপ্টে, dup
STDOUT ফাইল বর্ণনাকারীকে অন্য (অস্থায়ী) একটিতে লাইসেন্স দিতে পারেন, তারপরে নতুন তৈরি হওয়া অস্থায়ী ফাইলটিতে STDOUT পুনরায় খুলতে পারেন। এই বিন্দু থেকে, আপনার নিজের পার্ল স্ক্রিপ্ট থেকে সমস্ত STDOUT আউটপুট এবংsystem()
সেই স্ক্রিপ্টের সমস্ত কল সেই অস্থায়ী ফাইলটিতে শেষ হবে। হয়ে গেলে, আপনি dup
নিজের অস্থায়ী বর্ণনাকারীর কাছে নিজের স্টাটওটিটি পুনরায় সংরক্ষণ করতে পারেন এবং এটি পূর্বের মতো রয়েছে। আপনি এমনকি এই অস্থায়ী বর্ণনাকারীর কাছে লিখতে পারেন, সুতরাং আপনার আসল STDOUT আউটপুট অস্থায়ী ফাইলে গেলে আপনি এখনও বাস্তবে আউটপুট স্টাটটিকে সত্য STDOUT (সাধারণত ব্যবহারকারী) করতে পারেন।
উত্তর
আপনার প্রশ্নের উপরে বর্ণিত পটভূমি তথ্য প্রয়োগ করতে:
শেলটি কোন ক্রমে আদেশগুলি এবং স্ট্রিম পুনঃনির্দেশকে কার্যকর করে?
বাম থেকে ডান.
<command> > file.txt 2>&1
fork
একটি নতুন প্রক্রিয়া বন্ধ।
file.txt
ফাইল ডেস্ক্রিপ্টর 1 (STDOUT) এ এর পয়েন্টারটি খুলুন এবং সঞ্চয় করুন।
- STDERR (ফাইল বর্ণনাকারী 2) এফডি 1 পয়েন্ট এখনই যা যা (যা ইতিমধ্যে
file.txt
অবশ্যই খোলা আছে )।
exec
দ্য <command>
এটি স্পষ্টতই stderr কে প্রথমে stdout এ পুনঃনির্দেশ করে এবং তারপরে ফলাফল stdout file.txt এ পুনঃনির্দেশিত হয়।
এটি কেবলমাত্র একটি টেবিল থাকলে বোঝা যাবে , তবে উপরে বর্ণিত দুটি আছে। ফাইল বর্ণনাকারীরা একে অপরকে পুনরাবৃত্তভাবে নির্দেশ করছে না, "STDERR কে STDOUT এ পুনঃনির্দেশ করুন" তা ভাবার কোনও মানে হয় না। সঠিক চিন্তাটি "STDOR পয়েন্ট যেখানেই STDERR পয়েন্ট"। আপনি যদি পরে STDOUT পরিবর্তন করেন তবে STDERR যেখানেই থাকে সেখানেই থাকে, এটি STDOUT- তে আরও পরিবর্তনগুলির সাথে যাদুকরীভাবে যায় না।