উত্তর:
$ cat input.log | sed -e "s/^/$(date -R) /" >> output.log
কিভাবে এটা কাজ করে:
cat
ডাকা ফাইলটি পড়ে input.log
এবং কেবল এটির স্ট্যান্ডার্ড আউটপুট প্রিন্টে মুদ্রণ করে।
সাধারণত মান আউটপুট টার্মিনাল সাথে সংযুক্ত করা হয়, কিন্তু এই সামান্য স্ক্রিপ্ট রয়েছে |
যাতে শেল মান আউটপুট পুননির্দেশনা cat
মান ইনপুট sed
।
sed
ডেটা পড়ে (যেমন cat
এটি উত্পাদন করে), এটি প্রক্রিয়া করে ( -e
বিকল্পের সাথে সরবরাহিত স্ক্রিপ্ট অনুসারে ) এবং তারপরে এটির স্ট্যান্ডার্ড আউটপুটে মুদ্রণ করে। স্ক্রিপ্ট "s/^/$(date -R) /"
মানে date -R
কমান্ড দ্বারা উত্পন্ন পাঠ্যের প্রতিটি পংক্তির শুরুটি প্রতিস্থাপন করুন (প্রতিস্থাপন কমান্ডের জন্য সাধারণ নির্মাণ হ'ল s/pattern/replace/
)।
তারপরে একটি ফাইলের >>
bash
আউটপুটটিকে পুনঃনির্দেশিত অনুসারে ( মানে ফাইলের সামগ্রীগুলি প্রতিস্থাপন করা এবং তার মানে শেষের সাথে সংযোজন করা)।sed
output.log
>
>>
$(date -R)
আপনি স্ক্রিপ্টটি চালানোর সময় সমস্যাটি একবার মূল্যায়ন করা হয় যাতে এটি প্রতিটি লাইনের শুরুতে বর্তমান টাইমস্ট্যাম্প প্রবেশ করিয়ে দেয়। বর্তমান টাইমস্ট্যাম্প একটি বার্তা উত্পন্ন যখন একটি মুহুর্ত থেকে অনেক দূরে হতে পারে। এটি এড়ানোর জন্য আপনাকে বার্তাগুলি ক্রোন কাজের সাথে নয়, ফাইলটিতে লিখিত হওয়ার সাথে সাথে প্রক্রিয়া করতে হবে।
মান স্ট্রিম ফেরৎ নামক উপরে বর্ণিত নল । আপনি এটিকে কেবল |
স্ক্রিপ্টের কমান্ডগুলির মধ্যে দিয়ে নয়, তবে একটি ফিফো ফাইলের মাধ্যমে (ওরফে নাম পাইপ ) পাঠাতে পারেন । একটি প্রোগ্রাম ফাইলটিতে লিখবে এবং অন্যটি ডেটা পড়বে এবং এটি প্রথম প্রেরণের হিসাবে গ্রহণ করবে।
একটি উদাহরণ চয়ন করুন:
$ mkfifo foo.log.fifo
$ while true; do cat foo.log.fifo | sed -e "s/^/$(date -R) /" >> foo.log; done;
# have to open a second terminal at this point
$ echo "foo" > foo.log.fifo
$ echo "bar" > foo.log.fifo
$ echo "baz" > foo.log.fifo
$ cat foo.log
Tue, 20 Nov 2012 15:32:56 +0400 foo
Tue, 20 Nov 2012 15:33:27 +0400 bar
Tue, 20 Nov 2012 15:33:30 +0400 baz
কিভাবে এটা কাজ করে:
mkfifo
একটি নামক পাইপ তৈরি করে
while true; do sed ... ; done
অসীম লুপটি চালায় এবং প্রতিটি পুনরাবৃত্তিতে এটি তার স্ট্যান্ডার্ড ইনপুটটিতে sed
পুনর্নির্দেশের সাথে চলে foo.log.fifo
; sed
ইনপুট ডেটার জন্য অপেক্ষারত অবরুদ্ধ করে এবং তারপরে একটি প্রাপ্ত বার্তা প্রসেস করে এবং এটিকে পুনঃনির্দেশিত স্ট্যান্ডার্ড আউটপুটে প্রিন্ট করে foo.log
।
এই সময়ে আপনাকে একটি নতুন টার্মিনাল উইন্ডো খুলতে হবে কারণ লুপটি বর্তমান টার্মিনালটি দখল করে।
echo ... > foo.log.fifo
ফিফো ফাইলটিতে পুনঃনির্দেশিত তার স্ট্যান্ডার্ড আউটপুটে একটি বার্তা প্রিন্ট sed
করে এবং এটি গ্রহণ করে এবং প্রক্রিয়া করে এবং একটি নিয়মিত ফাইলে লেখেন।
গুরুত্বপূর্ণ নোটটি হ'ল ফিফো যেমন অন্য কোনও পাইপের কোনও ধারণা নেই তবে যদি এর কোনও দিক কোনও প্রক্রিয়াতে সংযুক্ত না থাকে। আপনি যদি কোনও পাইপে লেখার চেষ্টা করেন তবে কেউ কেউ পাইপের অপর পাশের ডেটা পড়তে না পারলে বর্তমান প্রক্রিয়াটি অবরুদ্ধ হবে । আপনি যদি কোনও পাইপ থেকে পড়তে চান তবে কেউ পাইপটিতে ডেটা না লিখলে প্রক্রিয়াটি অবরুদ্ধ হবে। sed
উদাহরণে লুপ উপরে কিছুই (ঘুমাবে), যে পর্যন্ত না আপনি কি করতে echo
।
আপনার নির্দিষ্ট পরিস্থিতির জন্য আপনি ফিফো ফাইলটিতে লগ বার্তা লিখতে আপনার অ্যাপ্লিকেশনটি কনফিগার করেছেন। আপনি যদি এটিটি কনফিগার করতে না পারেন - কেবল আসল লগ ফাইলটি মুছুন এবং একটি ফিফো ফাইল তৈরি করুন। তবে আবার মনে রাখবেন যে sed
লুপটি যদি কোনও কারণে মারা যায় - write
কেউ read
ফিফো থেকে না আসা পর্যন্ত আপনার প্রোগ্রামটি ফাইলটিতে চেষ্টা করার পরে অবরুদ্ধ করা হবে ।
সুবিধা বর্তমান টাইমস্ট্যাম্প মূল্যায়ন এবং প্রোগ্রাম ফাইলে এটা লিখেছেন কে একটি বার্তা সংযুক্ত।
tailf
লগতে লিখন এবং আরও স্বতন্ত্র প্রক্রিয়াকরণ করতে আপনি দুটি নিয়মিত ফাইল ব্যবহার করতে পারেন tailf
। একটি অ্যাপ্লিকেশন একটি কাঁচা ফাইলে বার্তা লিখবে এবং অন্যান্য প্রক্রিয়াতে নতুন লাইন পড়বে (অ্যাসিঙ্ক্রোনালি লিখতে অনুসরণ করুন) এবং দ্বিতীয় ফাইলটিতে লেখার সাথে ডেটা প্রক্রিয়া করবেন।
একটি উদাহরণ নেওয়া যাক:
# will occupy current shell
$ tailf -n0 bar.raw.log | while read line; do echo "$(date -R) $line" >> bar.log; done;
$ echo "foo" >> bar.raw.log
$ echo "bar" >> bar.raw.log
$ echo "baz" >> bar.raw.log
$ cat bar.log
Wed, 21 Nov 2012 16:15:33 +0400 foo
Wed, 21 Nov 2012 16:15:36 +0400 bar
Wed, 21 Nov 2012 16:15:39 +0400 baz
কিভাবে এটা কাজ করে:
tailf
প্রক্রিয়া চালান bar.raw.log
যা অসীম while read ... echo
লুপটিতে পুনঃনির্দেশিত প্রমিত আউটপুটগুলিতে তাদের লেখার মুদ্রণ করবে এবং প্রিন্ট করবে । এই লুপটি দুটি ক্রিয়া সম্পাদন করে: স্ট্যান্ডার্ড ইনপুট থেকে ডাকা বাফার ভেরিয়েবলের ডেটা পড়ুন line
এবং তারপরে নিম্নলিখিত বাফার ডেটা সহ উত্পন্ন টাইমস্ট্যাম্প লিখুন bar.log
।
কিছু বার্তা লিখুন bar.raw.log
। আপনাকে এটি একটি পৃথক টার্মিনাল উইন্ডোতে করতে হবে কারণ প্রথমটি দখল করা tailf
হবে যার দ্বারা রাইটগুলি অনুসরণ করবে এবং এর কাজ করবে। খুবই সাধারণ.
পেশাদাররা হ'ল যদি আপনি হত্যা করেন তবে আপনার আবেদন আটকাবে না tailf
। কনসটি সঠিক সঠিক টাইমস্ট্যাম্প এবং ডুপ্লিকেট লগ ফাইলগুলি।
tailf
, এটি সঠিকভাবে যুক্ত করার জন্য যুক্ত করে। প্রকৃতপক্ষে tailf
উপায়টি আরও মার্জিত বলে মনে হচ্ছে তবে আমি কারও উপকারে আসব এই প্রত্যাশা দিয়ে ফিফো পথটি ছাড়লাম।
আপনি ts
পার্ল স্ক্রিপ্ট থেকে ব্যবহার করতে পারেন moreutils
:
$ echo test | ts %F-%H:%M:%.S
2012-11-20-13:34:10.731562 test
দিমিত্রি ভ্যাসিল্যানভের উত্তর থেকে পরিবর্তিত।
বাশ স্ক্রিপ্টে, আপনি ফ্লাইয়ের লাইনে টাইমস্ট্যাম্প লাইন দিয়ে আউটপুটটিকে পুনর্নির্দেশ করতে এবং মোড়ানো করতে পারেন।
কখন ব্যবহার করতে হবে:
tailf
জন্য, দিমিত্রি ভ্যাসিল্যানভ যেমন বলেছিলেন তেমন লগ ফাইলের জন্য ব্যবহার করা আরও ভাল ।নামের একটি উদাহরণ foo.sh
:
#!/bin/bash
exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;)
echo "foo"
sleep 1
echo "bar" >&2
sleep 1
echo "foobar"
এবং ফলাফল:
$ bash foo.sh
$ cat foo.log
May 12 20:04:11 foo
May 12 20:04:12 bar
May 12 20:04:13 foobar
কিভাবে এটা কাজ করে
exec &>
Stdout এবং stderr একই জায়গায় পুনর্নির্দেশ করুন>( ... )
পাইপ আউটপুটগুলি একটি অ্যাসিনক্রোনাস ইনার কমান্ডের কাছে যায়উদাহরণ স্বরূপ:
পাইপ টাইমস্ট্যাম্প এবং ফাইল লগ
#!/bin/bash
exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;)
echo "some script commands"
/path-to/some-thrid-party-programs
অথবা টাইমস্ট্যাম্প প্রিন্ট করুন এবং স্টডআউটে লগ করুন
#!/bin/bash
exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line"; done;)
echo "some script commands"
/path-to/some-thrid-party-programs
তারপরে /etc/crontab
সেটিং এ সেভ করুন
* * * * * root /path-to-script/foo.sh >> /path-to-log-file/foo.log
আমি ts
স্ক্রিপ্টের জন্য একটি ত্রুটি লগটিতে টাইম স্ট্যাম্পের সাথে একটি এন্ট্রি পাওয়ার জন্য এই পদ্ধতিটি ব্যবহার করেছি যা আমি ক্যাকিটিকে একটি দূরবর্তী হোস্টের পরিসংখ্যানে ভরাট করতে ব্যবহার করি।
ক্যাকটি পরীক্ষার জন্য আমি rand
কয়েকটি এলোমেলো মান যুক্ত করতে ব্যবহার করি যা আমি আমার সিস্টেমের তাপমাত্রা পর্যবেক্ষণ করতে তাপমাত্রা গ্রাফের জন্য ব্যবহার করি।
পুশমনস্ট্যাটস.শ হ'ল একটি স্ক্রিপ্ট যা আমার পিসির সিস্টেমের তাপমাত্রার পরিসংখ্যান সংগ্রহ করে এবং এটি রাস্পবেরি পাইতে প্রেরণ করে যার উপর ক্যাকটি চালিত হয়। কিছু সময় আগে, নেটওয়ার্ক আটকে ছিল। আমি আমার ত্রুটি লগের মধ্যে কেবল এসএসএইচ সময় আউট পেয়েছি। দুর্ভাগ্যক্রমে, সেই লগের কোনও সময় প্রবেশ নেই। লগ এন্ট্রিতে কীভাবে টাইম স্ট্যাম্প যুক্ত করব তা আমি জানতাম না। সুতরাং, ইন্টারনেটে কিছু অনুসন্ধানের পরে, আমি এই পোস্টে হোঁচট খেয়েছি এবং এটিই আমি ব্যবহার করে তৈরি করেছি ts
।
এটি পরীক্ষা করার জন্য, আমি একটি অজানা বিকল্প ব্যবহার করেছি rand
। যা স্টাডারকে একটি ত্রুটি দিয়েছে। এটি ক্যাপচার করার জন্য, আমি এটি একটি অস্থায়ী ফাইলে পুনর্নির্দেশ করি। তারপরে আমি ফাইলের বিষয়বস্তুগুলি দেখানোর জন্য এবং এটিতে পাইপ দেওয়ার জন্য বিড়াল ব্যবহার করি ts
, একটি পোস্ট ফর্ম্যাট যা আমি এই পোস্টে পেয়েছি তা যোগ করুন এবং শেষ পর্যন্ত ত্রুটি ফাইলটিতে এটি লগইন করুন। তারপরে আমি অস্থায়ী ফাইলের বিষয়বস্তু সাফ করি, অন্যথায় আমি একই ত্রুটির জন্য ডাবল এন্ট্রি পাই।
নিম্নলিখিতরূপে crontab পরিবর্তন:
* * * * * /home/monusr/bin/pushmonstats.sh 1>> /home/monusr/pushmonstats.log 2> /home/monusr/.err;/bin/cat /home/monusr/.err|/usr/bin/ts %F-%H:%M:%.S 1>> /home/monusr/pushmonstats.err;> /home/monusr/.err
এটি আমার ত্রুটি লগতে নিম্নলিখিতটি দেয়:
2014-03-22-19:17:53.823720 rand: unknown option -- '-l'
এটি এটি করার জন্য খুব মার্জিত উপায় নয়, তবে এটি কার্যকর হয়। আমি আরও বিস্মিত হয় যদি এটিতে আরও মার্জিত পদ্ধতি রয়েছে।