কমান্ড লাইন থেকে পাইপ ছাড়াই বাশ স্ক্রিপ্ট টি ব্যবহার করতে বাধ্য করুন


20

আমার কাছে প্রচুর আউটপুট সহ একটি বাশ স্ক্রিপ্ট রয়েছে এবং আমি সমস্ত স্ক্রিপ্টটি কোনও ফাইলে অনুলিপি করতে সেই স্ক্রিপ্টটি (একটি নতুন তৈরি করতে চাই না) পরিবর্তন করতে চাই, ঠিক যেমনটি আমি যদি টিয়ের মাধ্যমে পাইপ করতাম তবে এটি ঘটত।

আমি একটি ফাইল আছে script.sh :

#!/bin/bash
init
do_something_that_outputs_stuff_to_STDOUT
launch_applications_that_output_to_STDOUT
fini

এবং আমি প্রতিবার টাইপ না করে কোনও ফাইল স্ক্রিপ্ট.লগে এসটিডিআউটের অনুলিপি তৈরি করতে চাই ./script.sh | tee script.log

ধন্যবাদ, টম


এটি আগে না বলে আমি দুঃখিত, তবে স্ক্রিপ্টটি বরং দীর্ঘ দীর্ঘ, এ কারণেই আমি একটি সহজ সমাধান খুঁজছি। সংযোজন | প্রতিটি লাইনে টি কিছুটা বেশি।
টম

উত্তর:


15

আমি ডেনিসের খুব সাধারণ ওয়ান-লাইনারকে কাজ করতে পারি না, সুতরাং এখানে আরও অনেক গুলিয়ে দেওয়া পদ্ধতি। আমি তার প্রথম চেষ্টা করব।

উল্লিখিত হিসাবে, আপনি পুরো স্ক্রিপ্টের জন্য স্ট্যান্ডার্ড ত্রুটি ও স্ট্যান্ডার্ড আউট রিডাইরেক্ট করতে এক্সিকিউট ব্যবহার করতে পারেন। ভালো লেগেছে:
exec > $LOGFILE 2>&1 এটি সমস্ত স্টাডার এবং stdout $ LOGFILE এ আউটপুট দেবে।

এখন, যেহেতু আপনি এটি কনসোলের পাশাপাশি একটি লগফাইলে প্রদর্শন করতে চান তাই আপনাকে এক্সিকিউটিভের জন্য একটি নামক পাইপ ব্যবহার করতে হবে, এবং পড়তে টিও করতে হবে।
(ডেনিসের ওয়ান-লাইনার প্রযুক্তিগতভাবে এটিও করে, যদিও স্পষ্টতই ভিন্ন উপায়ে) পাইপটি নিজেই তৈরি হয়েছিল mkfifo $PIPEFILE। তারপরে নিম্নলিখিতটি করুন।

# একটি লগফাইলে টি লেখা শুরু করুন, তবে আমাদের নামক পাইপ থেকে এটির ইনপুট টানুন।
টি $ লগফিল <$ পাইপ ফাইল এবং

# কমান্ডের জন্য টিয়ের প্রক্রিয়া আইডি ক্যাপচার করুন।
TEEPID = $!

# স্ট্যাডার বাকী পুনঃনির্দেশ করুন এবং আমাদের নামী পাইপে স্টাডআউট করুন।
এক্সিকিউট> $ পাইপ ফাইল 2> & 1

প্রতিধ্বনি "এখানে আপনার আদেশগুলি তৈরি করুন"
প্রতিধ্বনি "তাদের সমস্ত স্ট্যান্ডার্ড আউট ছিঁড়ে যাবে" "
প্রতিচ্ছবি "সুতরাং তাদের মান ত্রুটি হবে"> & 2

# স্টার্ডার এবং স্টডআউট ফাইলের বর্ণনাকারী বন্ধ করুন।
এক্সিকিউট 1> & - 2> এবং -

# টিপ শেষ হওয়ার অপেক্ষা করুন এখন থেকে পাইপের অন্য প্রান্তটি বন্ধ হয়ে গেছে।
অপেক্ষা করুন $ টিপিপিড

আপনি যদি পুরোপুরি হতে চান তবে আপনি আপনার স্ক্রিপ্টের শুরুতে এবং শেষে নামক পাইপ ফাইলটি তৈরি এবং ধ্বংস করতে পারেন।

রেকর্ডের জন্য, আমি এগুলির বেশিরভাগ এলোমেলো লোকের খুব তথ্যপূর্ণ ব্লগ পোস্ট থেকে সংগ্রহ করেছি : ( সংরক্ষণাগারিত সংস্করণ )


এটি সাইগউইনে কাজ করবে বলে মনে হয় না। :-(
ডকুটা

এই পোস্টটি শিক্ষার একটি ভাল কাজ করে। আপনাকে অনেক ধন্যবাদ.
ফিলিপ আলভারেজ

27

কেবল আপনার স্ক্রিপ্টের শুরুতে এটি যুক্ত করুন:

exec > >(tee -ia script.log)

এটি স্ট্যান্ডআউটে প্রেরিত সমস্ত আউটপুট ফাইলটিতে যুক্ত করবে script.log, পূর্ববর্তী বিষয়বস্তুগুলি স্থানে রেখে। আপনি যদি স্ক্রিপ্টটি প্রতিবার সতেজ শুরু করতে চান তবে rm script.logএই execকমান্ডের ঠিক আগে যুক্ত করুন বা কমান্ড -aথেকে মুছে ফেলুন tee

-iবিকল্প ঘটায় teeবিঘ্ন সংকেত উপেক্ষা করে অনুমতি দিতে পারে teeআরো একটি সম্পূর্ণ আউটপুট সেট ধরতে।

সমস্ত ত্রুটি (পৃথক ফাইলে) ধরার জন্য এই লাইনটি যুক্ত করুন:

exec 2> >(tee -ia scripterr.out)

একাধিক >চিহ্নের মধ্যে ফাঁকা স্থানগুলি গুরুত্বপূর্ণ।


খুব আকর্ষণীয় সমাধান।
haphink

2
আমি পোস্ট করা সমস্ত বকাবলের তুলনায় এটি এটি করার একটি সত্যিই মার্জিত উপায়। তবে আমি যখন এই দুটি লাইন দিয়ে একটি স্ক্রিপ্ট তৈরি করি তখন এটি স্তব্ধ হয়ে যায় এবং কখনই সঠিকভাবে বের হয় না।
ক্রিস্টোফার কারেল


RHEL5.3 ইনস্টলের অংশ হিসাবে GNU ব্যাশ, সংস্করণ 3.2.25 (1)। এটি প্রদর্শিত হয় এটি সরকারী সংগ্রহস্থলের সর্বশেষতম সংস্করণ।
ক্রিস্টোফার কারেল

আমি কেবল বাশ ৩.২.৪৯ (২৩) -র সাইগউইনের অধীনে এটি চেষ্টা করেছি -আমি দয়া করে ফাইল বিবরণ সংক্রান্ত ত্রুটি পেয়েছি। আমি বাশ 4.0.33 (1) - উবুন্টু 9.10-এ দয়া করে কাজ করি, তবে এটি কোনও বাশ 4 জিনিস হতে পারে।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

6

এটি ডেনিস উইলিয়ামসনের পোস্টের উত্তরের সম্মিলিত সংস্করণ। সঠিক ক্রমে স্ক্রিপ্ট.লগ এ দু'টি ভুল এবং স্ট্যান্ড আউট যুক্ত করে।

আপনার স্ক্রিপ্টের শুরুতে এই লাইনটি যুক্ত করুন:

exec > >(tee -a script.log) 2>&1

>লক্ষণগুলির মধ্যে স্থানটি নোট করুন । জিএনইউ ব্যাশ, সংস্করণ ৩.২.২৫ (১) -রিলিজ (x86_64-redhat-linux-gnu) এ আমার জন্য কাজ করে


5

আমি মনে করি যে অন্য একটি পদ্ধতির কিছু এইরকম:

#!/bin/bash

# start grouping at the top
{ 
    # your script goes here
    do_something_that_outputs_stuff_to_STDOUT
    launch_applications_that_output_to_STDOUT

# and at the bottom, redirect everything from the grouped commands
} 2>&1 | tee script.log 

3

আপনি যদি আউটপুটটির একটি অনুলিপি চান, আপনি teeএইভাবে ব্যবহার করতে পারেন :

  #!/bin/bash
  init
  do_something_that_outputs_stuff_to_STDOUT | tee script.log
  launch_applications_that_output_to_STDOUT | tee -a script.log
  fini

এটি তবে স্ক্রিপ্ট.লগে কেবল স্টডআউট লগ করবে। আপনি যদি নিশ্চিত করতে চান যে স্ট্ডার এবং স্টডআউট উভয়ই পুনঃনির্দেশিত হয়েছে, তবে ব্যবহার করুন:

  #!/bin/bash
  init
  do_something_that_outputs_stuff_to_STDOUT 2>&1 | tee script.log
  launch_applications_that_output_to_STDOUT 2>&1 | tee -a script.log
  fini

এমনকি আপনি এটি একটি সামান্য ফাংশন দিয়ে কিছুটা সুন্দর করতে পারেন:

  #!/bin/bash

  LOGFILE="script.log"
  # Wipe LOGFILE if you don't want to add to it at each run
  rm -f "$LOGFILE"

  function logcmd() {
        local cmd="$1" logfile=${LOGFILE:-script.log} # Use default value if unset earlier

        # Launch command, redirect stderr to stdout and append to $logfile
        eval '$cmd' 2>&1 | tee -a "$logfile"
  }

  init
  logcmd "do_something_that_outputs_stuff_to_STDOUT"
  logcmd "launch_applications_that_output_to_STDOUT"
  fini

ভাল উত্তর. যদি সে সত্যিই কেবল স্টডআউট সম্পর্কে চিন্তা করে তবে আমি কেবল 2>&1বাইরে চলে যাব এবং এটি টিপতে পাইপ করব।
ডেভপ্যারিলো

এটি সত্য, আমি কেবল স্টাডারকেই অন্তর্ভুক্ত করেছি কারণ ইগোরের পূর্ববর্তী উত্তর এটি পুনর্নির্দেশের যত্ন নিয়েছে এবং আমি ভেবেছিলাম এটি একটি ভাল ধারণা।
haphink

1

আপনি কেবল এটি ব্যবহার করবেন:

script logfile.txt
your script or command here

এটি স্ক্রিনে প্রদর্শন করার পাশাপাশি সেই লগতে সমস্ত কিছু আউটপুট করে। আপনি যদি পুরো আউটপুট চান তবে এটি এটি করা যায়।

এবং আপনি যদি অলস হন তবে আপনি স্ক্রিপ্টটি পুনরায় খেলতে পারেন।


scriptএটি প্যাকেজ, উদাহরণস্বরূপ লক্ষ্য করা ভাল হতে পারে । sudo apt-get install scriptএটি ডেবিয়ান স্বাদযুক্ত ডিস্ট্রোসে ইনস্টল করার জন্য , script -ac 'command opts' ~/Documents/some_log.scriptটার্মিনালের মধ্যে এমন কিছু মাধ্যমে পর্যালোচনা করা যেতে পারে strings ~/Documents/some_log.script | more; stringsএটি একটি সহজ উপায় হতে যে জিনিস কিছু প্রাক sanitize script উদ্বুদ্ধ অনুমতি দেওয়ার জন্য কল্পনাকারী পুনরায় প্লে / দৃশ্য পদ্ধতি। অন্যথায় একটি শক্ত উত্তর @ ফিশি, কারণ scriptইন্টারঅ্যাকটিভ জিনিসগুলিও সংরক্ষণ করে।
S0AndS0

0
#!/bin/bash
init
do_something_that_outputs_stuff_to_STDOUT > script.log 2>&1
launch_applications_that_output_to_STDOUT >> script.log 2>&1
fini

এটি এখানে কীভাবে কাজ করে সে সম্পর্কে আপনি আরও দেখতে পারেন: http://www.xaprb.com/blog/2006/06/06/ কি-does-devnull-21-mean/


1
আমি ইগোরের উত্তরে দ্বিতীয় লাইনে একটি দ্বিতীয়> যুক্ত করেছি যাতে এটি প্রথম লাইনে লেখা লগটি মুছে না দেয়।
ডগ হ্যারিস

1
তিনি যদিও একটি অনুলিপি চান, তাই তার ব্যবহার করা উচিত tee
5aphink

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