stdin
, stdout
, এবং stderr
হয় স্ট্রিম সংযুক্ত ফাইল বর্ণনাকারী 0, 1, এবং 2 একটি প্রক্রিয়ার যথাক্রমে।
টার্মিনাল বা টার্মিনাল এমুলেটরটিতে একটি ইন্টারেক্টিভ শেলের প্রম্পটে, এই 3 টি ফাইল বর্ণনাকারী একই ওপেন ফাইলের বিবরণ উল্লেখ করবে যা টার্মিনাল বা সিউডো-টার্মিনাল ডিভাইস ফাইল (যেমন কিছু /dev/pts/0
) খোলার মাধ্যমে প্রাপ্ত + লিখনে প্রাপ্ত হত মোড.
যদি সেই ইন্টারেক্টিভ শেল থেকে, আপনি কোনও পুনর্নির্দেশ ব্যবহার না করে আপনার স্ক্রিপ্টটি শুরু করেন, আপনার স্ক্রিপ্টটি সেই ফাইল বর্ণনাকারীদের উত্তরাধিকার সূত্রে প্রাপ্ত হবে।
লিনাক্স তারিখে /dev/stdin
, /dev/stdout
, /dev/stderr
প্রতি সিম্বলিক লিঙ্ক /proc/self/fd/0
, /proc/self/fd/1
, /proc/self/fd/2
যথাক্রমে নিজেদের প্রকৃত ফাইল ঐ ফাইল বর্ণনাকারী উপর খোলা থাকা অবস্থায় বিশেষ symlinks।
এগুলি স্টিডিন, স্টডআউট, স্টেডার নয়, এগুলি বিশেষ ফাইল যা সনাক্ত করে যে স্টিডিন, স্টডআউট, স্টার্ডার কোন ফাইলগুলিতে যায় (নোট করুন যে এটি লিনাক্সের তুলনায় অন্যান্য সিস্টেমে আলাদা আলাদা ফাইল রয়েছে)।
স্টিডিনের কাছ থেকে কিছু পড়ার অর্থ ফাইল বর্ণনাকারী 0 থেকে পড়া (যা ফাইলটি রেফারেন্স করে কোথাও নির্দেশ করবে /dev/stdin
)।
তবে $(</dev/stdin)
শেলটি স্টিডিন থেকে পড়ছে না, এটি স্ট্যান্ডিনের ওপেনের মতো একই ফাইলটিতে পড়ার জন্য একটি নতুন ফাইল বর্ণনাকারী খোলে (সুতরাং ফাইলের শুরু থেকে পড়া, যেখানে স্টিডিন বর্তমানে নির্দেশ করে)।
পঠন + রাইটিং মোডে টার্মিনাল ডিভাইসগুলির বিশেষ ক্ষেত্রে বাদে স্টাডআউট এবং স্ট্ডার সাধারণত পড়ার জন্য খোলা থাকে না। এগুলি বোঝায় আপনি যে স্ট্রিমগুলিতে লিখেছেন সেগুলি । সুতরাং ফাইল বিবরণী 1 থেকে পড়া সাধারণত কাজ করবে না। লিনাক্সে, খোলার /dev/stdout
বা /dev/stderr
পড়ার জন্য (যেমন হিসাবে $(</dev/stdout)
) কাজ করবে এবং আপনাকে স্টাডআউট যে ফাইলটি থেকে পড়তে দেয় (এবং যদি স্টডআউট পাইপ হয়, তবে পাইপের অন্য প্রান্ত থেকে পড়ত, এবং যদি এটি সকেট ছিল , এটি সকেট খুলতে না পারায় এটি ব্যর্থ হবে )।
টার্মিনালের ইন্টারেক্টিভ শেলের প্রম্পটে পুনর্নির্দেশ ছাড়াই স্ক্রিপ্টটি চালিত হওয়ার ক্ষেত্রে, / dev / stdin, / dev / stdout এবং / dev / stderr এর মধ্যে সমস্তই সেই / dev / pts / x টার্মিনাল ডিভাইস ফাইল হবে।
এই বিশেষ ফাইলগুলি থেকে পড়া টার্মিনাল দ্বারা প্রেরিত কী ফিরে আসে (কীবোর্ডে আপনি কী টাইপ করেন)। তাদের কাছে লেখা টেক্সটটি টার্মিনালে প্রেরণ করবে (প্রদর্শনের জন্য)।
echo $(</dev/stdin)
echo $(</dev/stderr)
একই হবে। প্রসারিত করতে $(</dev/stdin)
, শেলটি সেই / dev / pts / 0 টি খুলবে এবং ^D
খালি লাইনে চাপ না দেওয়া পর্যন্ত আপনি কী টাইপ করবেন তা পড়বে । তারপরে তারা সম্প্রসারণ (আপনি কী টাইপ করা নতুন লাইনের স্ট্রাইপ করেছেন এবং স্প্লিট + গ্লোব সাপেক্ষে) echo
পাস করবেন যা স্টাডআউটে প্রদর্শিত হবে (প্রদর্শনের জন্য)।
তবে এতে:
echo $(</dev/stdout)
মধ্যে bash
( এবং bash
শুধুমাত্র ), এটা যে ভিতরে উপলব্ধি করা জরুরী $(...)
, stdout- এ পুনঃনির্দেশিত করা হয়েছে। এটি এখন একটি পাইপ। এর ক্ষেত্রে bash
, একটি শিশু শেল প্রক্রিয়া ফাইলের সামগ্রী (এখানে /dev/stdout
) পড়ছে এবং পাইপটিতে লিখছে, যখন পিতামাতারা প্রান্তটি প্রসারিত করতে অন্য প্রান্ত থেকে পড়ে।
এই ক্ষেত্রে যখন শিশু বাশ প্রক্রিয়াটি খোলে /dev/stdout
, এটি আসলে পাইপের পঠন প্রান্তটি খুলছে । এর থেকে আর কিছুই আসবে না, এটি একটি অচলাবস্থার পরিস্থিতি।
আপনি যদি স্ক্রিপ্টস স্টডআউট দ্বারা নির্দেশিত ফাইলটি পড়তে চেয়েছিলেন তবে আপনি এটির সাথে কাজ করতে চাইবেন:
{ echo content of file on stdout: "$(</dev/fd/3)"; } 3<&1
এটি এফডি 1 টি এফডি 3 এর প্রতিলিপি তৈরি করবে, সুতরাং / dev / fd / 3 একই ফাইলটিকে / dev / stdout হিসাবে নির্দেশ করবে।
এর মতো স্ক্রিপ্ট সহ:
#! /bin/bash -
printf 'content of file on stdin: %s\n' "$(</dev/stdin)"
{ printf 'content of file on stdout: %s\n' "$(</dev/fd/3)"; } 3<&1
printf 'content of file on stderr: %s\n' "$(</dev/stderr)"
যখন চালান:
echo bar > err
echo foo | myscript > out 2>> err
আপনি out
পরে দেখতে পাবেন :
content of file on stdin: foo
content of file on stdout: content of file on stdin: foo
content of file on stderr: bar
যেন থেকে পড়া উল্টোদিকে /dev/stdin
, /dev/stdout
, /dev/stderr
, আপনি stdin, stdout- এ এবং দ্বারা stderr (যা এমনকি কম জানার জন্য হবে) থেকে পড়তে চান, তাহলে আপনি করতে চাই:
#! /bin/sh -
printf 'what I read from stdin: %s\n' "$(cat)"
{ printf 'what I read from stdout: %s\n' "$(cat <&3)"; } 3<&1
printf 'what I read from stderr: %s\n' "$(cat <&2)"
আপনি যদি দ্বিতীয় স্ক্রিপ্টটি আবার শুরু করেন:
echo bar > err
echo foo | myscript > out 2>> err
আপনি দেখতে পাবেন out
:
what I read from stdin: foo
what I read from stdout:
what I read from stderr:
এবং ইন err
:
bar
cat: -: Bad file descriptor
cat: -: Bad file descriptor
স্টাডআউট এবং স্টডারারের জন্য cat
ব্যর্থ হয়েছে কারণ ফাইল বর্ণনাকারী কেবল লেখার জন্যই ছিল না, পড়ার জন্য নয়, এর প্রসারণ $(cat <&3)
এবং $(cat <&2)
খালি ছিল।
আপনি যদি এটি হিসাবে ডাকেন:
echo out > out
echo err > err
echo foo | myscript 1<> out 2<> err
(যেখানে <>
ছাঁটাই ছাড়াই পঠন + লেখার মোডে খোলে), আপনি এতে দেখতে পাবেন out
:
what I read from stdin: foo
what I read from stdout:
what I read from stderr: err
এবং ইন err
:
err
আপনি লক্ষ্য করবেন যে কিছুই stdout- এ থেকে পড়া হয়েছে, কারণ পূর্ববর্তী printf
বিষয়বস্তুর ওভাররাইট ছিল out
সঙ্গে what I read from stdin: foo\n
এবং যে ফাইল পরেই মধ্যে stdout- এ অবস্থান ত্যাগ করেন। আপনি যদি out
আরও কিছু বৃহত্তর পাঠ্য নিয়ে প্রতিজ্ঞা করেছিলেন তবে:
echo 'This is longer than "what I read from stdin": foo' > out
তারপরে আপনি প্রবেশ করতে পারেন out
:
what I read from stdin: foo
read from stdin": foo
what I read from stdout: read from stdin": foo
what I read from stderr: err
দেখুন কীভাবে $(cat <&3)
প্রথমটির পরে যা পড়েছিল তা কীভাবে পড়েছে printf
এবং এটি করার ফলে স্টাডাউট অবস্থানটি এর আগেও স্থানান্তরিত হয়েছিল যাতে পরবর্তীটি printf
পড়ার পরে কী ফলাফল হয়।
echo x
asecho x > /dev/stdout
উদাহরণস্বরূপ, যদি স্টডআউট একটি নিয়মিত ফাইল যায়echo x > /dev/stdout
তবে ফাইলটি কেটে ফেলা হবে এবং বর্তমান স্টডআউট পজিশনেx\n
লেখার পরিবর্তে এর সামগ্রীটি প্রতিস্থাপন করবেx\n
।