প্রতিধ্বনি বা মুদ্রণ / দেব / স্টিডিন / দেব / স্টডআউট / দেব / স্টডার


13

আমি / dev / stdin, / dev / stdout এবং / dev / stderr এর মান মুদ্রণ করতে চাই।

আমার সরল লিপিটি এখানে:

#!/bin/bash
echo your stdin is : $(</dev/stdin)
echo your stdout is : $(</dev/stdout)
echo your stderr is : $(</dev/stderr)

আমি নিম্নলিখিত পাইপ ব্যবহার:

[root@localhost home]# ls | ./myscript.sh
[root@localhost home]# testerr | ./myscript.sh

কেবল $(</dev/stdin)কাজ করা বলে মনে হচ্ছে, আমি অন্যদের কাছেও ব্যবহার করা প্রশ্নগুলি পেয়েছি: "${1-/dev/stdin}"সাফল্য ছাড়াই এটি চেষ্টা করে।

উত্তর:


29

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পড়ার পরে কী ফলাফল হয়।


2

stdoutএবং ফলাফল stderrহয়, আপনি তাদের কাছ থেকে পড়েন না আপনি কেবল তাদের কাছে লিখতে পারেন। উদাহরণ স্বরূপ:

echo "this is stdout" >/dev/stdout
echo "this is stderr" >/dev/stderr

প্রোগ্রামগুলি ডিফল্টরূপে stdout এ লিখতে থাকে তাই প্রথমটিটির সমতুল্য

echo "this is stdout"

এবং আপনি স্টাডারকে অন্য উপায়ে পুনর্নির্দেশ করতে পারেন

echo "this is stderr" 1>&2

1
লিনাক্সে, স্টডআউট কোনও পাইপ বা টিটিআই ডিভাইসের মতো কিছু অক্ষর ডিভাইসে যায় না echo xas echo x > /dev/stdoutউদাহরণস্বরূপ, যদি স্টডআউট একটি নিয়মিত ফাইল যায় echo x > /dev/stdoutতবে ফাইলটি কেটে ফেলা হবে এবং বর্তমান স্টডআউট পজিশনে x\nলেখার পরিবর্তে এর সামগ্রীটি প্রতিস্থাপন করবে x\n
স্টাফেন চেজেলাস

@ মাইকেল-ড্যাফিন> আপনাকে ধন্যবাদ, তাই আমি যদি স্টাডাউট এবং স্টেডার পড়তে চাই তবে আমি কেবল বিড়াল ব্যবহার করতে পারি? (যেহেতু তারা ফাইল), উদাহরণস্বরূপ আমি ব্যবহারকারীকে শেষ ত্রুটিটি দেখাতে চাই echo this is your error $(cat /dev/stderr)?
ওমর বিস্তামি

@ ওমবিবিস্টামি আপনি যেখান থেকে পড়তে পারবেন না stdoutএবং stderrসেগুলি আউটপুট।
কুসালানন্দ

1

myscript.sh:

#!/bin/bash
filan -s

তারপরে চালান:

$ ./myscript.sh
    0 tty /dev/pts/1
    1 tty /dev/pts/1
    2 tty /dev/pts/1

$ ls | ./myscript.sh
    0 pipe 
    1 tty /dev/pts/1
    2 tty /dev/pts/1

$ ls | ./myscript.sh > out.txt
$ cat out.txt
    0 pipe 
    1 file /tmp/out.txt
    2 tty /dev/pts/1

আপনি সম্ভবত ইনস্টল করতে হবে filanসঙ্গে sudo apt install socatপ্রথম।

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