जारी रखने से पहले बैश स्क्रिप्ट स्थिति संदेश की प्रतीक्षा करें


10

मैं सेलेनियम सर्वर को बैश स्क्रिप्ट के साथ निकाल रहा हूं और जैसा कि आप नीचे दिए गए लॉग पर टाइमस्टैम्प से देख सकते हैं, इस चीज को पूरी तरह से ऑनलाइन आने में लगभग 32 सेकंड लगते हैं:

Feb 28, 2012 10:19:02 PM org.openqa.grid.selenium.GridLauncher main
INFO: Launching a standalone server
22:19:02.835 INFO - Java: Sun Microsystems Inc. 20.0-b11
22:19:02.836 INFO - OS: Linux 2.6.32-220.4.1.el6.x86_64 amd64
22:19:02.852 INFO - v2.19.0, with Core v2.19.0. Built from revision 15849
22:19:02.988 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
22:19:02.990 INFO - Version Jetty/5.1.x
22:19:02.992 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver]
22:19:02.993 INFO - Started HttpContext[/selenium-server,/selenium-server]
22:19:02.993 INFO - Started HttpContext[/,/]
22:19:34.552 INFO - Started org.openqa.jetty.jetty.servlet.ServletHandler@488e32e7
22:19:34.552 INFO - Started HttpContext[/wd,/wd]
22:19:34.555 INFO - Started SocketListener on 0.0.0.0:4444
22:19:34.555 INFO - Started org.openqa.jetty.jetty.Server@7d29f3b5

सर्वर शुरू करने के बाद "स्लीप 32" कमांड का उपयोग करने के बजाय (स्क्रिप्ट को आगे बढ़ने से पहले देरी करने के लिए), मैं अपनी बैश स्क्रिप्ट को प्रतीक्षा करना चाहूंगा जब तक कि यह "स्टार्टेड सॉकेटलिस्ट" को नहीं देखता है, और फिर जारी रखें। क्या यह संभव है?

जवाबों:


8

tail -fजैसे-जैसे यह बढ़ता है, आप फ़ाइल से पढ़ने के लिए उपयोग कर सकते हैं । आप जो खिलाते हैं, उससे सावधान रहें tail -f। आप tail -fएक फिल्टर में पाइप कर सकते हैं जो वांछित लॉग लाइन तक इंतजार करता है और क्विट करता है। यदि आप tail -fकिसी ऐसे फ़िल्टर में पाइप करते हैं जो किसी अन्य फ़िल्टर में पाइप करता है तो क्या काम नहीं करेगा , क्योंकि मध्यवर्ती फ़िल्टर इसके आउटपुट को बफर कर देगा। यह काम:

: >file.log  # create an empty log file
start-selenium-session --log-file=file.log &
{ tail -n +1 -f file.log & } | sed -n '/Started SocketListener/q'
speak-to-socket

ध्यान दें कि मैंने tailपृष्ठभूमि में रखा है। ऐसा इसलिए है क्योंकि जब sedवांछित लाइन मिल जाती है, तो वह बाहर निकल जाती है, लेकिन पाइपलाइन तब तक चलती रहती है जब तक tailकि अगली लाइन का इंतजार किया जाता है, जो हो सकता है तो तुरंत नहीं आए। tailअगली लाइन आने पर बाहर निकल जाएगा और इसे ए प्राप्त होगा SIGPIPE। यह एक आवारा tailप्रक्रिया को छोड़ सकता है यदि लॉग को बिना किसी लाइन के हटा दिया जाता है ( tailप्रक्रिया की पीआईडी ​​प्राप्त करना जब इसे sedबाहर निकालना संभव होगा लेकिन मुश्किल होगा)।

¹ पुराने संस्करण में बग को इंगित करने के लिए पीटरओ को धन्यवाद ।


एक नोट (पैदल सेना, शायद) - मैं किसी भी ऐसे गोले को नहीं जानता जो वास्तव में खाली फाइल लिखने की अनुमति के लिए एक शून्य की आवश्यकता है।
क्रिस डाउन

@ क्रिसडाउन न तो मैं करता हूं। लेकिन मुझे स्पष्ट रूप से नो-ऑप लिखना स्पष्ट है।
गिलेस एसओ- बुराई को रोकना '

नीस (+1) ... बफ़र्स की बात: मैं बफ़रिंग माचेन्स को नहीं समझता, लेकिन इसके बारे में जागरूक होने के लिए एक मुद्दा है, अगर टारगेट लाइन को तुरंत अधिक लॉग लाइन्स द्वारा फॉलो नहीं किया जाता है। यह तब तक लटका रहता है जब तक कि अधिक पंक्तियाँ नहीं लिखी जाती हैं, भले ही sed पहले से ही पैटर्न से मेल खाता हो (<- मुझे वह हिस्सा समझ में नहीं आता)। एक संशोधित sedकमांड जो फ्लश (?) को मजबूर करने के लिए लॉग को पर्याप्त लिखती है, तुरंत इसे (मैंने इसे परीक्षण किया) पर किक करता है, लेकिन मुझे लगता है कि इसमें सम्मिलित डेटा की संभावना सेलेनियम-सत्र लाइन के साथ इंटरसेप्टर होती है। ।
पीटर

@ पीटर.ओ.आई.आई। आई। आर। सी। कुछ सीरियस इम्प्लीमेंटेशन अगली पंक्ति को पहले से पढ़ते हैं, क्योंकि ऐसे मामले हैं जहाँ यह उपयोगी है ( $पता, एक के लिए)। मैंने अपने परीक्षणों में ऐसा नहीं देखा, हालांकि (GNU sed के साथ)। वास्तव में आपने किस ओएस पर बग का प्रदर्शन किया?
गाइल्स का SO- 12-12 पर '

@ गिल्स: paste.ubuntu.com/863326 .. और: GNU sed संस्करण 4.2.1 , पूंछ (GNU
कोरुटिल्स

3

स्ट्रेट शेल स्क्रिप्ट में यह थोड़ा कठिन है, लेकिन यह वह है जो मैं काफी समय से टॉमकैट और ओशन 4 जे के लिए उपयोग कर रहा था:

perlscr='
alarm 120;
open F, "<$ARGV[0]";
seek F -($ARGV[1]*80),2;
while (1) {exit if (<F>=~$ARGV[2]);}'

window=10
scanfor="^INFO: Server startup in \d+ ms"
perl -e "$perlscr" $logfile $window "$scanfor" 2>&1 0<&1

alarmकिसी भी संभावित फांसी जहां बिल्ला में विफल रहा है संभाल लेंगे। EOF से वापस जाने के लिए लाइनों की संख्या समायोज्य (एक विन्यास फ़ाइल से) है।

मैंने अंततः पूरी बात अजगर को स्थानांतरित कर दी; जबकि यह थोड़ा लंबा है, यह थोड़ा अधिक कुशल है:

class Alarm:
    import signal
    signal_signal = signal.signal
    signal_SIGALRM = signal.SIGALRM
    signal_SIG_DFL = signal.SIG_DFL
    del signal
    def __init__(self, delay)
       self.howlong = delay
       self.clear()
    def __del__(self):
       self.reset_signals()
    def __nonzero__(self):
       return self.state
    def clear(self):
       self.state = False
       self.reset_signals()
    def _start_alarm(self):
       from signal import alarm
       alarm(self.howlong)
    def _set_sigalarm(self, handler):
        if handler:
            self.signal_signal(self.signal_SIGALRM, handler)
        else:
            self.signal_signal(self.signal_SIGALRM, self.signal_SIG_DFL)
    def reset_signals(self):
        self._set_sigalarm(None)
    def set_signals(self):
        self._set_sigalarm(self.handler)
    def handler(self, signo, frame):
        self.state = False
    def start(self):
        self.state = True
        self.set_signals()
        self._start_alarm()
    def stop(self):
        self.reset_signals()
        self.state = False
found = False
scanfor = re.compile('^INFO: Server startup in \d+ ms')
window = 10
logfile = open(logfilename, 'r')
logfile.seek(window * 80, 2)
alarm = Alarm(timeout)
try:
    alarm.start()
    while alarm:
        line = logfile.readline()
        if line:
            m = scanfor.search(line)
            if m:
                alarm.stop()
                found = True
                break
        time.sleep(0.1)
finally:
    alarm.clear()

1

विराम लागू करने के लिए आप इसे अपनी स्क्रिप्ट में जोड़ सकते हैं:

perl -e 'use File::Tail;
    my $ref=tie *FH,"File::Tail",(name=>"/var/log/messages",maxinterval=>1);
    while(<FH>) { exit if /Started SocketListener/ };'

यह पर्ल फ़ाइल का उपयोग करता है :: टेल मॉड्यूल जैसे व्यवहार करने के लिए tail -f logfile | grep Started SocketListener

उपयुक्त लॉग फ़ाइल के साथ बदलें / var / log / संदेश। ध्यान दें कि यह हमेशा के लिए लटका रहेगा यदि "स्टार्टेड सॉकेटलिस्ट" कभी प्रकट नहीं होता है।


1

हो सकता है कि आपको अनिश्चित काल तक प्रतीक्षा करने के बजाय टाइमआउट का उपयोग करना चाहिए।

नीचे दिए गए बैश फ़ंक्शन तब तक ब्लॉक हो जाएंगे जब तक कि दिए गए खोज शब्द प्रकट नहीं होते हैं या एक निश्चित समय समाप्त हो जाता है।

बाहर निकलने की स्थिति 0 होगी यदि स्ट्रिंग टाइमआउट के भीतर पाई जाती है।

wait_str() {
  local file="$1"; shift
  local search_term="$1"; shift
  local wait_time="${1:-5m}"; shift # 5 minutes as default timeout

  (timeout $wait_time tail -F -n0 "$file" &) | grep -q "$search_term" && return 0

  echo "Timeout of $wait_time reached. Unable to find '$search_term' in '$file'"
  return 1
}

शायद सेलेनियम लॉन्च करने के बाद अभी तक लॉग फ़ाइल मौजूद नहीं है। उस स्थिति में, आपको स्ट्रिंग की खोज करने से पहले उसके प्रदर्शित होने की प्रतीक्षा करनी चाहिए:

wait_selenium_server() {
  echo "Waiting for Selenium server..."
  local server_log="$1"; shift
  local wait_time="$1"; shift

  wait_file "$server_log" 10 || { echo "Selenium log file missing: '$server_log'"; return 1; }

  wait_str "$server_log" "Started SocketListener" "$wait_time"
}

wait_file() {
  local file="$1"; shift
  local wait_seconds="${1:-10}"; shift # 10 seconds as default timeout

  until test $((wait_seconds--)) -eq 0 -o -f "$file" ; do sleep 1; done

  ((++wait_seconds))
}

यहां बताया गया है कि आप इसका उपयोग कैसे कर सकते हैं:

wait_selenium_server "/var/log/selenium.log" 5m && \
echo -e "\n-------------------------- Selenium READY --------------------------\n"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.