কীভাবে কোনও ফাইলে স্টাডাউট, এবং স্টাডআউট + স্ট্ডারকে অন্য একটিতে পুনর্নির্দেশ করবেন?


32

কীভাবে অর্জন করতে পারি

cmd >> file1 2>&1 1>>file2

যে, stdout এবং stderr একটি ফাইল (ফাইল 1) এ পুনঃনির্দেশ করা উচিত এবং শুধুমাত্র stdout (ফাইল 2) অন্য একটি (পুনরায় সংশোধন মোডে) পুনঃনির্দেশ করা উচিত?

উত্তর:


41

সমস্যাটি হ'ল আপনি যখন নিজের আউটপুটটিকে পুনর্নির্দেশ করবেন তখন পরবর্তী পুনঃনির্দেশের জন্য এটি আর উপলভ্য নয়। teeদ্বিতীয় পুনঃনির্দেশের জন্য আউটপুট রাখার জন্য আপনি একটি সাব-শেইলে পাইপ করতে পারেন :

( cmd | tee -a file2 ) >> file1 2>&1

বা আপনি যদি টার্মিনালে আউটপুট দেখতে চান:

( cmd | tee -a file2 ) 2>&1 | tee -a file1

প্রথম দ্বারা stderr যোগ এড়াতে teeকরার file1, আপনি কিছু ফাইল বর্ণনাকারী (3 উদাঃ) এর কমান্ডের দ্বারা stderr পুনর্নির্দেশ করা উচিত এবং পরে আবার stdout- এ এই যোগ করুন:

( 2>&3 cmd | tee -a file2 ) >> file1 3>&1
# or
( 2>&3 cmd | tee -a file2 ) 3>&1 | tee -a file1

(ধন্যবাদ @ ফ্রে-সান)


16

সাথে zsh:

cmd >& out+err.log > out.log

সংযোজন মোডে:

cmd >>& out+err.log >> out.log

ইন zsh, এবং প্রদত্ত mult_iosবিকল্পটি অক্ষম করা হয়নি, যখন কোনও ফাইল বর্ণনাকারী (এখানে 1) লেখার জন্য বেশ কয়েকবার পুনঃনির্দেশিত হয়, তখন শেলটি teeসমস্ত লক্ষ্যবস্তুতে আউটপুট নকল করতে একটি অন্তর্নির্মিত প্রয়োগ করে।


আমি বাইরে কি চিন্তা করতে পারে না out+errএবং outএখানে মানে। ফাইলের নাম? পুনঃনির্দেশিত করা হবে স্ট্রিমস?
গ্রোনস্টাজ

@ গ্রনোস্টাজ ভাবেন যে কমান্ডটি পড়েছেcmd >& file1 > file2
আইজাক

এই সমাধানটি আউটপুট উত্পন্ন হওয়ার ক্রমটি সংরক্ষণ করবে। স্টাডাউট এবং স্ট্ডারকে প্রকৃতপক্ষে সঞ্চয় করতে (সেই ক্রমে) আপনার আলাদা পদ্ধতির প্রয়োজন।
আইজ্যাক

1
@ আইসাক, আদেশটি অগত্যা সংরক্ষণ করা হবে না কারণ স্টাডআউট আউটপুটটি পাইপের মধ্য দিয়ে যাবে (এমন একটি প্রক্রিয়া যা এটি প্রতিটি ফাইলে প্রেরণ করে) যখন স্ট্যাডার আউটপুট সরাসরি ফাইলে যাবে। কোনও অবস্থাতেই, এটি স্ট্যান্ডআউটটির পরে ওপেন স্ট্যাডার আউটপুট আসতে বলে বলে মনে হচ্ছে না।
স্টাফেন চেজেলাস

3

আপনি পারবেন: ট্যাগ স্টডআউট (একটি ইউএনবিফুফার্ড শেড ব্যবহার করে, অর্থাৎ:), স্টাডার স্টাডআউটেও sed -u ...যেতে পারেন (অবিকৃত, যেহেতু এটি ট্যাগিং সেডের মধ্য দিয়ে যায় নি), এবং ফলস্বরূপ লগফাইলে 2 টি পার্থক্য করতে সক্ষম হবেন।

নিম্নলিখিতটি ধীরে ধীরে (কিছুক্ষণের পরিবর্তে পার্ল স্ক্রিপ্ট উদাহরণের জন্য ব্যবহার করে এটি গুরুতরভাবে অনুকূল করা যেতে পারে ... উদাহরণস্বরূপ, করণীয়; উদাহরণস্বরূপ, যা প্রতিটি লাইনে সাবশেল এবং কমান্ড তৈরি করবে!), অদ্ভুত (মনে হচ্ছে একটি স্ট্যান্ডআউটের নতুন নামকরণের জন্য আমার 2}} পর্যায়ে প্রয়োজন হবে এবং তারপরে অন্যটিতে "স্ট্যাডারের মাধ্যমে" এতে পতিত হয়ে যুক্ত করুন ") ইত্যাদি etc. তবে এটি হ'ল" ধারণার প্রমাণ ", যা রাখার চেষ্টা করবে আউটপুট আদেশ যতটা সম্ভব stdout এবং stderr সর্বাধিক:

#basic principle (some un-necessary "{}" to visually help see the layers):
# { { complex command ;} | sed -e "s/^/TAGstdout/" ;} 2>&1 | read_stdin_and_redispatch

#exemple:
# complex command = a (slowed) ls of several things (some existing, others not)
#  to see if the order of stdout&stderr is kept

#preparation, not needed for the "proof of concept", but needed for our specific exemple setup:
\rm out.file out_AND_err.file unknown unknown2 
touch existing existing2 existing3

#and the (slow, too many execs, etc) "proof of concept":
uniquetag="_stdout_" # change this to something unique, that will NOT appear in all the commands outputs... 
                     # avoid regexp characters ("+" "?" "*" etc) to make it easy to remove with another sed later on.

{
   { for f in existing unknown existing2 unknown2 existing3 ; do ls -l "$f" ; sleep 1; done ;
   } | sed -u -e "s/^/${uniquetag}/" ;
} 2>&1 | while IFS="" read -r line ; do
    case "$line" in
       ${uniquetag}*) printf "%s\n" "$line" | tee -a out_AND_err.file | sed -e "s/^${uniquetag}//" >> out.file ;; 
        *)            printf "%s\n" "$line"       >> out_AND_err.file ;;   
    esac; 
done;

# see the results:
grep "^" out.file out_AND_err.file

এটি বোঝা সত্যিই কঠিন। (1) আপনি ls unknownস্ট্যাডারের উপর কিছু মুদ্রণের জন্য কেন এই জাতীয় জটিল ব্যবহারের কেস ব্যবহার করেন ? >&2 echo "error"ঠিক আছে। (২) teeএকবারে একাধিক ফাইল যুক্ত করতে পারে। (3) কেন শুধু catপরিবর্তে না grep "^"? (৪) স্ট্যাডার আউটপুট শুরু হওয়ার সাথে সাথে আপনার স্ক্রিপ্ট ব্যর্থ হবে _stdout_। (৫) কেন?
pLumo

@ রভো: প্রথম দুটি মন্তব্য করা লাইনগুলি অ্যালগরিদম দেখায়, ধারণার উদাহরণের প্রমাণের চেয়ে সহজ। 1): ls loopএটি স্টাডআউট এবং স্ট্ডার উভয়ই আউটপুট তৈরি করবে, মিশ্রিত (বিকল্পভাবে), একটি নিয়ন্ত্রিত ক্রমে, যাতে আমরা পরীক্ষা করতে পারি যে স্টাডআউট 2-র সত্ত্বেও আমরা সেই স্ট্যাডার / স্টাডআউট অর্ডার রেখেছি): গনু লেজ, তবে, না নিয়মিত লেজ (প্রাক্তন, আইক্সে।)। 3): গ্রেপ "^" উভয় ফাইলের নামও দেখায়। 4): এটি পরিবর্তনশীল দ্বারা পরিবর্তন করা যেতে পারে। 5): সংশ্লেষিত উদাহরণটি পুরাতন মলদ্বারে (প্রাক্তন, পুরাতন আইক্স) কাজ করে যেখানে আমি এটি পরীক্ষা করেছি (কোনও পার্ল উপলব্ধ নেই)।
অলিভিয়ার ডুলাক

(1) স্টার্ডার এবং স্টাউটের একাধিক প্রতিধ্বনি ভাল হবে, তবে ঠিক আছে, গুরুত্বপূর্ণ নয়, কেবল পড়া সহজ হবে। (3) সম্মত হন, (4) নিশ্চিত, তবে এটি ব্যর্থ হবে যদি ভেরিয়েবলের যা থাকে তা দিয়ে এটি শুরু হয়। (5) আমি দেখতে।
pLumo

@ রোভো আমি আপনার 1 এর সাথে একমত) 4) এর জন্য, পিবি অদৃশ্য হয়ে যাওয়ার জন্য ভেরিয়েবলটি যতটা জটিল হতে পারে (উদা: uniquetag="banaNa11F453355B28E1158D4E516A2D3EDF96B3450406...)
অলিভিয়ার ডুলাক

1
অবশ্যই নিশ্চিত, এটি খুব সম্ভবত নয়, তবে যাইহোক এটি পরে কোনও সুরক্ষা সমস্যা প্রবর্তন করতে পারে। এবং তারপরে আপনি ফাইলটি মুদ্রণ করার আগে সেই স্ট্রিংটি অপসারণ করতে চাইতে পারেন ;-)
pLumo

2

যদি আউটপুট ক্রম হতে হবে: stdout তারপর stderr ; কেবল পুনঃনির্দেশ সহ কোনও সমাধান নেই।
Stderr একটি টেম্পোরাল ফাইল সংরক্ষণ করা আবশ্যক

cmd 2>>file-err | tee -a file1 >>file2
cat file-err >> file1
rm file-err

বর্ণনা:

একটি আউটপুট (stdout বা stderr এর মতো একটি fd) দুটি ফাইলে পুনর্নির্দেশের একমাত্র উপায় এটি পুনরুত্পাদন করা। teeএকটি ফাইল বর্ণনাকারী সামগ্রী পুনরুত্পাদন করার জন্য কমান্ডটি সঠিক সরঞ্জাম। সুতরাং, দুটি ফাইলে একটি আউটপুট রাখার প্রাথমিক ধারণাটি হ'ল:

... |  tee file1 file2

এটি উভয় ফাইল (1 এবং 2) তে টিয়ের স্টিডিন পুনরুত্পাদন করে টিয়ের আউটপুটটিকে এখনও অব্যবহৃত রেখে দেয়। তবে আমাদের সংযোজন (ব্যবহার -a) করতে হবে এবং কেবল একটি অনুলিপি প্রয়োজন। এটি উভয় সমস্যার সমাধান করে:

... | tee -a file1 >>file2

teeস্টাডাউট সরবরাহ করতে (যার পুনরাবৃত্তি করতে হবে) আমাদের সরাসরি কমান্ডের বাইরে স্ট্যাডার ব্যবহার করতে হবে। একটি উপায়, যদি আদেশ গুরুত্বপূর্ণ না হয় (আউটপুট ক্রম (সম্ভবত) উত্পাদিত হিসাবে সংরক্ষণ করা হবে, যেটি আউটপুট প্রথমে প্রথমে সংরক্ষণ করা হবে)। উভয় ক্ষেত্রেই:

  1. cmd 2>>file1 | tee -a file2 >>file1
  2. cmd 2>>file1 > >( tee -a file2 >>file1 )
  3. ( cmd | tee -a file2 ) >> file1 2>&1

বিকল্প 2 কেবলমাত্র কয়েকটি শেলের মধ্যে কাজ করে। বিকল্প 3টিতে অতিরিক্ত সাবশেল (ধীর) ব্যবহার করা হয় তবে কেবল একবার ফাইলের নাম ব্যবহার করুন।

তবে যদি স্টাডআউটটি অবশ্যই প্রথম হতে পারে (যেকোন অর্ডার আউটপুট উত্পন্ন হয়) শেষে এটি ফাইলের জন্য যুক্ত করতে আমাদের স্টেডার সংরক্ষণ করতে হবে (প্রথম সমাধান পোস্ট করা হয়েছে)।


1
বা মেমোরিতে রাখার মতো সঞ্চয় করুন sponge:(cmd | tee -a out >> out+err) 2>&1 | sponge >> out+err
স্টাফেন চেজেলাস

1

বিভিন্নতার স্বার্থে:

যদি আপনার সিস্টেম সমর্থন করে /dev/stderr, তবে

(cmd | tee -a /dev/stderr) 2>> file1 >> file2

কাজ করবে. স্ট্যান্ডআউট cmd এবং পাইপলাইনের স্ট্যাডার উভয়ের কাছে স্ট্যান্ডার্ড আউটপুট প্রেরণ করা হয়। cmdবাইপাসগুলির স্ট্যান্ডার্ড ত্রুটিtee পাইপলাইনের স্টারারকে এবং বেরিয়ে আসে।

সুতরাং

  • পাইপলাইনটির স্টাডআউটটি কেবল স্টাডআউট cmd এবং
  • পাইপলাইনটির স্টারডার হ'ল আন্তঃসমীক্ষিত স্ট্যান্ডআউট এবং স্টডার cmd

এই স্ট্রিমগুলি সঠিক ফাইলগুলিতে প্রেরণ করা সহজ বিষয়।

এর মতো প্রায় কোনও পদ্ধতির মতো ( স্টাফেনের উত্তর সহ ) file1লাইনগুলি ক্রমবর্ধমান হতে পারে।

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