bash 스크립트를 사용하여 Selenium 서버를 시작하고 아래 로그의 타임 스탬프에서 볼 수 있듯이 항목이 완전히 온라인 상태가 되려면 약 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
서버를 시작한 후 “sleep 32″명령을 사용하는 대신 (이동하기 전에 스크립트를 지연시키기 위해) bash 스크립트가 “Started SocketListener”라는 문자열이 나타날 때까지 기다렸다가 계속 진행하고 싶습니다. 가능합니까?
답변
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
all¹ 즉시 경우 제공되지 않을 수 다음 줄을 기다리고 있습니다. tail
다음 줄이 오면 종료되고가 나타납니다 SIGPIPE
. tail
로그에 줄을 쓰지 않고 제거하면 길 잃은 프로세스 가 남을 수 있습니다 ( 종료가 가능하지만 까다로운 경우 로그 tail
를 죽이는 프로세스 의 PID를 얻음 sed
).
¹ 이전 버전의 버그를 지적한 Peter.O 에게 감사합니다 .
답변
스트레이트 쉘 스크립트에서는 조금 더 어렵지만 이것은 바람둥이와 oc4j에 꽤 오랫동안 사용하고있는 것입니다.
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()
답변
이를 일시 중지를 구현하기 위해 스크립트에 추가 할 수 있습니다.
perl -e 'use File::Tail;
my $ref=tie *FH,"File::Tail",(name=>"/var/log/messages",maxinterval=>1);
while(<FH>) { exit if /Started SocketListener/ };'
perl File :: Tail 모듈을 사용하여처럼 동작합니다 tail -f logfile | grep Started SocketListener
.
/ var / log / message를 적절한 로그 파일로 바꾸십시오. “Started SocketListener”가 나타나지 않으면 영원히 중단됩니다.
답변
무한정 기다리는 대신 타임 아웃을 사용해야 할 수도 있습니다.
아래의 bash 함수는 주어진 검색어가 나타나거나 주어진 시간이 초과 될 때까지 차단됩니다.
문자열이 시간 초과 내에 발견되면 종료 상태는 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
}
아마도 Selenium을 시작한 직후에 로그 파일이 존재하지 않을 수 있습니다. 이 경우 문자열을 검색하기 전에 표시 될 때까지 기다려야합니다.
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"