কিভাবে শেল স্ক্রিপ্টের ভিতরে স্ক্রিন এবং ফাইল উভয় পাঠ্য আউটপুট করবেন?


49

বর্তমানে আমার কাছে একটি শেল স্ক্রিপ্ট রয়েছে যা এই জাতীয় লগ ফাইলে বার্তা লগ করে:

log_file="/some/dir/log_file.log"
echo "some text" >> $log_file
do_some_command
echo "more text" >> $log_file
do_other_command

এই স্ক্রিপ্টটি সম্পাদন করার সময়, স্ক্রিনে কোনও আউটপুট নেই, এবং যেহেতু আমি পুটিয়ের মাধ্যমে সার্ভারের সাথে সংযোগ করছি, আমাকে অন্য সংযোগটি খুলতে হবে এবং "টেইল -f লগ_ফাইল_পাথ.লগ" করতে হবে, কারণ আমি দৌড়াতে পারি না স্ক্রিপ্ট এবং আমি আউটপুটটি রিয়েল টাইমে দেখতে চাই।

স্পষ্টতই, আমি যা চাই তা হ'ল পাঠ্য বার্তাগুলি স্ক্রিনে এবং ফাইলে মুদ্রিত হয়েছে তবে আমি এটি দুটি লাইনে নয় একটি লাইনেই করতে চাই, যার একটিতে ফাইলের পুনঃনির্দেশ নেই।

কীভাবে এটি অর্জন করবেন?

উত্তর:


71

এইটা কাজ করে:

command | tee -a "$log_file"

teeকোনও ফাইলে ইনপুট সংরক্ষণ করে ( -aওভাররাইটের পরিবর্তে সংযোজন করার জন্য ব্যবহার করুন) এবং ইনপুটটিকে স্ট্যান্ডার্ড আউটপুটেও অনুলিপি করে।


8

আপনি এখানে একটি ডক এবং ব্যবহার করতে পারেন। এটি দক্ষ, পসিক্স-বান্ধব সাধারণ সংগ্রহকারী মডেলের জন্য উত্স করুন।

. 8<<-\IOHERE /proc/self/fd/8

command
 
fn() { declaration ; } <<WHATEVER
# though a nested heredoc might be finicky
# about stdin depending on shell
WHATEVER
cat -u ./stdout | ./works.as >> expect.ed
IOHERE

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

হেরডোকের বিষয়বস্তুগুলি আপনার নির্দিষ্ট করা ফাইল বর্ণনাকারীর কাছে প্রবাহিত হয়, যা পরে শেল-কোড হিসাবে ব্যাখ্যা করা হয় এবং দ্বারা সম্পাদিত হয়। অন্তর্নির্মিত, তবে এর জন্য কোনও নির্দিষ্ট পথ নির্দিষ্ট না করেই নয়। । যদি / প্রোক / স্ব পাথ আপনাকে সমস্যা দেয় / ডিভ / এফডি / এন বা / প্রো / / trouble চেষ্টা করে $$ পাইপগুলিতে এই একই পদ্ধতিটি কাজ করে:

cat ./*.sh | . /dev/stdin

এটি দেখতে যতটা না বোধহয় কম বুদ্ধিমান। আপনি অবশ্যই sh দিয়ে একই কাজটি করতে পারেন তবে, এর উদ্দেশ্য হ'ল বর্তমান শেল পরিবেশে চালানো, যা সম্ভবত আপনি চান, এবং আপনার শেলের উপর নির্ভর করে হেরডোকের সাথে কাজ করার সম্ভাবনা অনেক বেশি একটি স্ট্যান্ডার্ড বেনামে পাইপ সঙ্গে।

যাইহোক, আপনি সম্ভবত লক্ষ্য করেছেন, আমি এখনও আপনার প্রশ্নের উত্তর পাই নি। তবে আপনি যদি এটির বিষয়ে চিন্তা করেন, ঠিক একইভাবে হেরডোক আপনার কোডগুলি সমস্ত স্রোতে প্রবেশ করে, ইনস, এটি আপনাকে একটি একক, সরল, আউটপয়েন্টও সরবরাহ করে:

. 5<<EOIN /dev/fd/5 |\ 
    tee -a ./log.file | cat -u >$(tty)
script
 
more script
EOIN

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

আপনি দ্বিতীয় উদাহরণে অনুপস্থিত ব্যাকস্ল্যাশ উদ্ধৃতিটিও প্রশ্ন করতে পারেন। এই অংশটি আপনি ঝাঁপ দেওয়ার আগে বোঝা গুরুত্বপূর্ণ এবং এটি কীভাবে ব্যবহার করা যায় সে সম্পর্কে আপনাকে কয়েকটি ধারণা দিতে পারে। একটি উদ্ধৃত বংশগত সীমাবদ্ধ (এখনও অবধি আমরা IOHERE এবং EOIN ব্যবহার করেছি, এবং প্রথমটি আমি ব্যাকস্ল্যাশ দিয়ে উদ্ধৃত করেছি, যদিও 'একক' বা "ডাবল" উদ্ধৃতি একই উদ্দেশ্যে কাজ করবে) শেলটি কোনও পরামিতি সম্প্রসারণ করতে বাধা দেবে বিষয়বস্তু, কিন্তু একটি অনাদায়ী সীমাবদ্ধ এর বিষয়বস্তু প্রসারিত খোলা ছেড়ে দেবে। আপনার উত্তরাধিকারী যখন এর পরিণতি। উত্সাহিত নাটকীয়:

. 3<<HD ${fdpath}/3
: \${vars=$(printf '${var%s=$((%s*2))},' `seq 1 100`)} 
HD
echo $vars
> 4,8,12 
echo $var1 $var51
> 4 104

কারণ আমি হেরডোক সীমাবদ্ধকে উদ্ধৃত করি নি শেলটি এতে পড়ার সাথে সাথে ফলাফলটি ফাইল বর্ণনাকারীর পরিবেশন করার আগে সামগ্রীগুলি প্রসারিত করেছিল। চালানো. এটি মূলত কমান্ডগুলিকে দুবার পার্স করার ফলে - যাইহোক প্রসারযোগ্য ones কারণ আমি ব্যাকস্ল্যাশটি sh ওয়ার্সের প্যারামিটার সম্প্রসারণের শেলটি প্রথম পাসে তার ঘোষণাটিকে অগ্রাহ্য করে এবং কেবল ব্যাকস্ল্যাশটি ছিনিয়ে নিয়েছি যাতে পুরো প্রিন্টফ প্রসারিত সামগ্রীগুলি নাল দ্বারা মূল্যায়ন করা যায়। দ্বিতীয় পাসে স্ক্রিপ্ট উত্সাহিত।

এই কার্যকারিতাটি মূলত বিপজ্জনক ইওল শেল বিল্টিনই সরবরাহ করতে পারে ঠিক তেমনই, এমনকি কোটেশনটি হ'ল ওষুধের তুলনায় হেরেডকে হ্যান্ডেল করা খুব সহজ এবং সমানভাবে বিপজ্জনকও হতে পারে। আপনি যদি এটি সাবধানতার সাথে পরিকল্পনা না করেন তবে অভ্যাসের বিষয় হিসাবে "ইওএফ" সীমাবদ্ধতার উদ্ধৃতি দেওয়া ভাল। এমনি বলছি.

সম্পাদনা: হ্যাঁ, আমি এটিকে ফিরে দেখছি এবং ভাবছি এটি কিছুটা প্রসারিত। আপনার যা যা করতে হবে সব হ'ল একটি পাইপে বিভিন্ন আউটপুট একত্রিত করতে হয় তবে সহজ পদ্ধতিটি কেবল একটি ব্যবহার করা:

{ or ( command ) list ; } | tee -a ea.sy >>pea.sy

কার্লিগুলি বর্তমান শেলটিতে সামগ্রীগুলি চালনার চেষ্টা করবে যেখানে প্যারেনগুলি স্বয়ংক্রিয়ভাবে সাব-আউট হবে। তবুও, যে কেউ আপনাকে এটি বলতে পারে এবং কমপক্ষে আমার মতে,। বংশগতি সমাধান অনেক বেশি মূল্যবান তথ্য, বিশেষত যদি আপনি বুঝতে চান যে শেলটি আসলে কীভাবে কাজ করে।

আনন্দ কর!


3

একটি ইনস্টল লগ লিখতে একটি ইনস্টল স্ক্রিপ্ট পরিবর্তন করার জন্য যখন আমি এই উত্তরটি পেয়েছি।

আমার স্ক্রিপ্ট ইতিমধ্যে প্রতিধ্বনি বিবৃতি পূর্ণ:

echo "Found OLD run script $oldrunscriptname"
echo "Please run OLD tmunsetup script first!"

এবং আমি এটি চালানোর জন্য কোনও টি স্টেটমেন্ট চাইনি (বা অন্য স্ক্রিপ্টটি বিদ্যমানটিকে টি দিয়ে কল করুন), তাই আমি এটি লিখেছিলাম:

#!/bin/bash
# A Shell subroutine to echo to screen and a log file

LOGFILE="junklog"

echolog()
(
echo $1
echo $1 >> $LOGFILE
)


echo "Going"
echolog "tojunk"

# eof

সুতরাং এখন আমার মূল স্ক্রিপ্টে, আমি কেবল 'ইকো' পরিবর্তন করে 'ইকলোজ' করতে পারি যেখানে লগ ফাইলে আউটপুট চাই।

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