পাঠ্য না হওয়া পর্যন্ত `পুচ্ছ -ফ text


20

আমি একটি কমান্ড-লাইন ইন্টারফেস সহ একটি সিআই সার্ভার পেয়েছি যা আমাকে দূরবর্তীভাবে একটি কাজ ( jenkinsসিআই সার্ভার এবং jenkins-cli.jarসরঞ্জাম) থেকে সরিয়ে ফেলতে দেয়।

আমি চাকরীটি সরিয়ে দেওয়ার পরে আমি tail -fলগ (অগোছালো আদেশের জন্য দুঃখিত):

ssh -t my-jenkins-host.com "tail -f \"/var/lib/jenkins/jobs/$job_name/builds/\`ls -ltr /var/lib/jenkins/jobs/$job_name/builds/ | grep '^l' | tail -n 1|awk '{print \$9}'\`/log\""

কাজটি সফলতার সাথে শেষ হওয়ার পরে সাধারণত কমপক্ষে 5 মিনিটের পরে, আউটপুটটিতে আমি নিম্নলিখিত লাইনটি পাই:

Finished: SUCCESS

এই সময়ে লগটি টেলিং বন্ধ করার কোনও ভাল উপায় আছে কি? অর্থাৎ tail_until 'some line' my-file.logকমান্ডের মতো আছে ?

বোনাস: যদি আপনি কোনও সাপ্লাই মেলে যখন 0, ব্যর্থতা মিলে যায় তখন 1, এবং আপনার সমাধান ম্যাকের সাথে কাজ করে এমন কোনও জবাব সরবরাহ করতে পারে তবে অতিরিক্ত ক্রেডিট! (যা আমি বিশ্বাস করি বিএসডি ভিত্তিক)

উত্তর:


39

আপনি যে লাইনটি সন্ধান করছেন তা যখন দেখাবে তখন এটি বন্ধ করতে বলার tail -fজন্য আপনি পাইপ করতে পারেন sed:

tail -f /path/to/file.log | sed '/^Finished: SUCCESS$/ q'

sedএটি প্রতিটি লাইনটি ডিফল্টরূপে প্রসেস করে এবং লাইনটি দেখার পরে প্রস্থান করবে। tailপ্রক্রিয়া যখন এটি পরের লাইনে লিখতে চেষ্টা করে এবং দেখেন তার আউটপুট নল নষ্ট হয়ে গেছে বন্ধ করবে


বুহ হ্যা! নিখুঁত। ... সুতরাং যে কোনও সুযোগে 0 থেকে বেরিয়ে আসার কোনও উপায় আছে যদি আমি একটি জিনিস মেলে ('সাফল্য' বলি) এবং 1 যদি আমি অন্য কোনও কিছুর সাথে মেলে (সম্ভবত 'ব্যর্থতা')?
অ্যারোনস্টেসি

7
@ অ্যারোনস্টেসি আপনি যদি জিএনইউ গ্রেপ ব্যবহার করেন, qকমান্ডটি একটি alচ্ছিক প্রস্থান কোড নেয়। সুতরাং sedকমান্ড হবেsed '/^Finished: SUCCESS$/ q0; /^Finished: FAILURE$/ q1'
মাইকেল Mrozek

6
Finished: SUCCESSআউটপুট
lk-

@ মিশেল মরোজেক আন্ড এবং অবশ্যই আমি বি / সি নই আমি
ফ্রিগিন

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

6
tail -f my-file.log | grep -qx "Finished: SUCCESS"

-qঅর্থ শান্ত, এটি মিল খুঁজে পাওয়ার সাথে সাথেই প্রস্থান করে

-xgrepপুরো লাইন মেলে তোলে

দ্বিতীয় অংশের জন্য, চেষ্টা করুন

tail -f my-file.log | grep -m 1 "^Finished: " | grep -q "SUCCESS$"

-m <number>গ্রেপকে সংখ্যা ম্যাচের পরে থামতে বলে

এবং grep -qপ্রস্থান স্থিতিটি কেবলমাত্র 0যদি SUCCESSলাইনের শেষে পাওয়া যায়

আপনি যদি সমস্ত আউটপুট দেখতে চান grep -qতবে আপনি ব্যবহার করতে পারবেন না , তবে আপনি এখনও করতে পারেন

tail -f my-file.log | grep -m 1 "^Finished: "

যদি FAILUREউপস্থিত হয় তবে প্রস্থান স্থিতি সেট করা ব্যতীত যা কিছু ঘটে ।


5
আমি grepআমার উত্তরটি মূলত ব্যবহার করেছি, তবে তিনি যদি ব্যবহার করছেন tail -fতবে সম্ভবত তিনি ফাইলটি আউটপুট দেখতে চান; grepমধ্যবর্তী সমস্ত লাইন দেখানো যাচ্ছে না
মাইকেল মরোজেক

4

@ ম্রিজেকের মন্তব্যে @ মাইকেলের উত্তরের একটি পরিবর্তন (আমি মন্তব্যে উত্তর দিয়েছি তবে আমার মনে হয় আমার এখনও যথেষ্ট সুযোগ-সুবিধা নেই)

tail -f my-file.log | tee >( grep -qx "Finished: SUCCESS" )

আপনাকে @ মাইকেলের সমাধানটি ব্যবহার করতে এবং এখনও পর্দায় আউটপুট দেখতে দেবে


আমরা কি এর সাথে একটি টাইমআউট ইন্টারভাল যুক্ত করতে পারি, যেমন: "এটি যদি 60 থেকে 120 সেকেন্ডের মধ্যে না পড়ে, তবে লেজটি বাতিল করে দিন এবং শেলের মধ্যে একটি ত্রুটি প্রস্থান কোড দেবে"?
কিলটেক

2

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

#!/bin/bash
while IFS= read -r LOGLINE || [[ -n "$LOGLINE" ]]; do
    printf '%s\n' "$LOGLINE"
    [[ "${LOGLINE}" == "Finished: SUCCESS" ]] && exit 0
    [[ "${LOGLINE}" == "Finished: FAILURE" ]] && exit 1
done < <(timeout 300 tail -f my-file.log)
exit 3

এছাড়াও অন্তর্ভুক্ত একটি টাইমআউট বৈশিষ্ট্য, যার ফলস্বরূপ 3 এর প্রস্থান কোড হবে 3 যদি আপনার সিস্টেমে টাইমআউট কমান্ড না থাকে তবে অ্যান্টনি থাইসেন থেকে টাইমআউট.শ স্ক্রিপ্টটি ধরুন:

http://www.ict.griffith.edu.au/anthony/software/timeout.sh

নীচের মতামত অনুসারে, পালানোর চরিত্রের প্রসার বন্ধ করতে আমি লগ প্রিন্ট আপডেট করেছি এবং স্ট্যান্ডার্ড 'রিড' এর সমস্ত বৈশিষ্ট্য অন্তর্ভুক্ত করেছি। সম্পূর্ণ 'পঠিত' বিশদগুলির জন্য /programming//a/10929511 দেখুন । ইওএফ চেক এখানে প্রয়োজন হয় না, কিন্তু সম্পূর্ণতার জন্য অন্তর্ভুক্ত করা হয়।


খুব সুন্দর. while IFS= read -r LOGLINEশেল থেকে লাইনগুলিতে সাদা স্পেস বিভক্ত হওয়া রোধ করতে ব্যবহার করার কথা বিবেচনা করুন tail
রোয়াইমা

@ রোয়াইমা: readযখন কেবলমাত্র একটি মাত্র পরিবর্তনশীল থাকে তখন বিভক্ত হয় না (এবং এটির সাথে অ্যারেও নয় -a) তবে -rইনপুট ডেটাতে ব্যাকস্ল্যাশ থাকলে আপনার প্রয়োজন হবে do তবে যদি ইনপুট ডেটাতে ব্যাকস্ল্যাশ থাকে তবে echo "$var"আপনার শেল এবং / অথবা সিস্টেমের উপর নির্ভর করে printf '%s\n' "$line"
স্ক্রুও


0

এখানে একটি অজগর স্ক্রিপ্ট যা আমি যা চাই প্রায় তা করে (নীচে সতর্কীকরণ দেখুন):

import sys,re

def main():
    re_end = re.compile(sys.argv[1])
    re_fail = re.compile(sys.argv[2]) if len(sys.argv) > 2 else None
    for line in sys.stdin:
        sys.stdout.write(line)
        if re_end.match(line):
            sys.exit(0)
        elif re_fail and re_fail.match(line):
            sys.exit(1)

if __name__ == '__main__': main()

আদেশ সহকারে:

  • লাইনগুলি আসার সাথে সাথে মুদ্রণ করা হয় না ... তারা দলে ছাপা হচ্ছে ... মনে হচ্ছে কিছুটা বাফার হচ্ছে

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


আপডেট: tailমনে হচ্ছে এটি একই বাফারিংয়ের কাজ করে, সুতরাং আমি অনুমান করছি যে এটি এমন কিছু নয় যা আশপাশে কাজ করার চেষ্টা করা উচিত।
অ্যারোনস্টেসি

0

আমি সঙ্গে সমস্যা ছিল sedএবং grepএবং তাদের বিকল্প, তাই আমি খনি লিখতেone with bash conditions

tail -f screenlog.* | 
while IFS= read line; 
 do 
   echo $line; 
   if [[ $line == *Started\ Application* ]]; 
    then pkill tail; 
   fi; 
done

-1

আপনিও চেষ্টা করে দেখুন

 grep -q 'App Started' <(tail -f /var/log/app/app.log)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.