সম্পাদনা: আমি দেখতে পাচ্ছি যে আমি লাইনচ্যুত হয়েছি এবং জিজ্ঞাসা করা ব্যক্তির থেকে আলাদা প্রশ্নের উত্তর দিয়ে শেষ করেছি। আসল প্রশ্নের উত্তর পল টম্বলিনের উত্তরের নীচে রয়েছে। (আপনি যদি কোনও কারণে স্টাডাউট এবং স্টডারকে আলাদাভাবে পুনর্নির্দেশের জন্য সেই সমাধানটি বাড়িয়ে তুলতে চান তবে আপনি এখানে বর্ণিত কৌশলটি ব্যবহার করতে পারেন))
আমি একটি উত্তর চাই যা স্টাডাউট এবং স্টাডারের মধ্যে পার্থক্য সংরক্ষণ করে। দুর্ভাগ্যক্রমে এখনও অবধি দেওয়া সমস্ত উত্তর যে এই পার্থক্যটি সংরক্ষণ করে রেস-প্রবণ: এগুলি অসম্পূর্ণ ইনপুট দেখে প্রোগ্রাম ঝুঁকিপূর্ণ করে আমি মন্তব্যগুলিতে উল্লেখ করেছি।
আমি মনে করি অবশেষে আমি একটি উত্তর পেয়েছি যা পার্থক্য সংরক্ষণ করে, রেসের ঝুঁকিপূর্ণ নয়, এবং ভয়ঙ্করভাবে বিব্রতও নয়।
প্রথম বিল্ডিং ব্লক: স্টাডাউট এবং স্টডারকে অদলবদল করতে:
my_command 3>&1 1>&2 2>&3-
দ্বিতীয় বিল্ডিং ব্লক: যদি আমরা কেবল স্টার্ডার ফিল্টার করতে চাইতাম (উদাহরণস্বরূপ টি) আমরা স্টাডাউট এবং স্ট্ডার অদলবদল, ফিল্টারিং এবং তারপরে ফিরে অদলবদল করে এটি সম্পাদন করতে পারি:
{ my_command 3>&1 1>&2 2>&3- | stderr_filter;} 3>&1 1>&2 2>&3-
এখন বাকিটি সহজ: আমরা শুরুতে একটি স্টাডাউট ফিল্টার যুক্ত করতে পারি:
{ { my_command | stdout_filter;} 3>&1 1>&2 2>&3- | stderr_filter;} 3>&1 1>&2 2>&3-
বা শেষে:
{ my_command 3>&1 1>&2 2>&3- | stderr_filter;} 3>&1 1>&2 2>&3- | stdout_filter
নিজেকে বোঝাতে যে উপরের দুটি আদেশই কাজ করে, আমি নিম্নলিখিতগুলি ব্যবহার করেছি:
alias my_command='{ echo "to stdout"; echo "to stderr" >&2;}'
alias stdout_filter='{ sleep 1; sed -u "s/^/teed stdout: /" | tee stdout.txt;}'
alias stderr_filter='{ sleep 2; sed -u "s/^/teed stderr: /" | tee stderr.txt;}'
আউটপুট হল:
...(1 second pause)...
teed stdout: to stdout
...(another 1 second pause)...
teed stderr: to stderr
এবং আমার প্রম্পট teed stderr: to stderr
প্রত্যাশার সাথে সাথেই " " এর পরে ফিরে আসবে।
Zsh সম্পর্কে পাদটীকা :
উপরের সমাধানটি ব্যাশে কাজ করে (এবং সম্ভবত কিছু অন্যান্য শাঁস, আমি নিশ্চিত নই), তবে এটি zsh এ কাজ করে না। এটি zsh এ ব্যর্থ হওয়ার দুটি কারণ রয়েছে:
- সিনট্যাক্স
2>&3-
zsh দ্বারা বোঝা যায় না; যে হিসাবে আবার লিখতে হবে2>&3 3>&-
- zsh এ (অন্যান্য শাঁসের বিপরীতে), যদি আপনি ইতিমধ্যে উন্মুক্ত কোনও ফাইল বর্ণনাকারীকে পুনর্নির্দেশ করেন তবে কিছু ক্ষেত্রে (এটি কীভাবে সিদ্ধান্ত নেয় আমি সম্পূর্ণ বুঝতে পারি না) এটি পরিবর্তে একটি অন্তর্নিবিষ্ট টি-জাতীয় আচরণ করে। এটি এড়াতে, আপনাকে প্রতিটি এফডি এটি পুনঃনির্দেশ করার আগে বন্ধ করতে হবে।
সুতরাং, উদাহরণস্বরূপ, আমার দ্বিতীয় সমাধানটি zsh এর জন্য আবার লিখতে হবে {my_command 3>&1 1>&- 1>&2 2>&- 2>&3 3>&- | stderr_filter;} 3>&1 1>&- 1>&2 2>&- 2>&3 3>&- | stdout_filter
(যা কাজ করে, তবে ভয়াবহভাবে ভার্বোস হয়)।
অন্যদিকে, আপনি zsh এর আরও কম সংক্ষিপ্ত সমাধান পেতে zsh এর রহস্যময় অন্তর্নিহিত অন্তর্নিহিত টিজিংয়ের সুবিধা নিতে পারেন, যা মোটেও টি চালায় না:
my_command >&1 >stdout.txt 2>&2 2>stderr.txt
(আমি যে দস্তাবেজগুলি দেখেছি তা অনুমান করতাম না যে আমি >&1
এবং 2>&2
এটিই ছিল যা zsh এর অন্তর্নিহিত টিজকে ট্রিগার করে; আমি এটি পরীক্ষামূলক-ত্রুটি দ্বারা খুঁজে পেয়েছি))