텍스트가 보일 때까지`tail -f`


20

작업을 원격으로 시작할 수있는 명령 줄 인터페이스 ( jenkinsCI 서버 및 jenkins-cli.jar도구)가 있는 CI 서버가 있습니다.

내가 일을 시작한 후 나는 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명령이 있습니까?

보너스 : SUCCESS가 일치하면 0, FAILURE가 일치하면 1을 반환하고 솔루션이 Mac에서 작동하는 경우 답변을 제공 할 수있는 경우 추가 크레딧입니다! (내 생각에 bsd 기반이라고 생각합니다)

답변:


39

당신 파이프 수 tail -f에를 sed, 그것은 선 당신을 위해있는 거 검색을 볼 때 종료를 말하는 :

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

sed기본적으로 처리하는 각 줄을 출력하고 해당 줄을 본 후 종료합니다. tail는 다음 줄을 쓰려고하고 출력 파이프가 고장 볼 때 프로세스가 중지됩니다


으악! 완전한. ... 어쩌면 내가 한 가지 ( '성공')와 일치하면 0을 끝내고 ( '실패'와 같은) 다른 것과 일치하면 1을 종료하는 방법이 있습니까?
aaronstacy

7
@aaronstacy GNU grep을 사용하는 경우 q명령은 선택적 종료 코드를 사용합니다. 그렇게 sed명령이 될 것이다sed '/^Finished: SUCCESS$/ q0; /^Finished: FAILURE$/ q1'
마이클 Mrozek

6
Finished: SUCCESS마지막 출력 라인 인 경우에는 작동하지 않을 수 있습니다
lk-

@Michael Mrozek는 aaaand 물론 나는 B / 난 빌어 먹을 맥을 사용하고 c를하지 않아요
aaronstacy

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에게 멈추도록 지시합니다.

그리고 grep -q종료 상태 만 될 0경우 SUCCESS행의 끝에서 발견된다

모든 출력을 보려면을 사용할 grep -q수 없지만 여전히 할 수는 있습니다

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

FAILURE표시 되면 종료 상태를 1로 설정하는 것을 제외한 모든 작업을 수행 합니다.


5
나는 grep원래 내 대답에 사용 했지만 그가 사용하고 있다면 tail -f아마도 파일 출력을보고 싶을 것입니다. grep모든 중간 선을 표시하지 않을
마이클 Mrozek

4

@Mrozek의 의견에 대한 @Mikel의 답변 변형 (댓글에 답글을 달았지만 아직 충분한 권한이 없다고 생각합니다)

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

@Mikel의 솔루션을 사용하고 여전히 화면에서 출력을 볼 수 있습니다.


"60 초에서 120 초 사이를 읽지 않으면 꼬리를 중단하고 쉘에서 오류 종료 코드를 제공하십시오"와 같이 시간 초과 간격을 추가 할 수 있습니까?
kiltek

2

나는 여기에 답을 좋아하지 않았으므로 내 자신을 굴리기로 결정했습니다. 이 bash 스크립트는 모든 기준을 충족하며 실패시 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을 초래하는 시간 종료 기능도 포함되어 있습니다. 시스템에 시간 종료 명령이없는 경우 Anthony Thyssen의 timeout.sh 스크립트를 가져 오십시오.

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

아래 주석에 따라 이스케이프 문자 확장을 중지하고 표준 '읽기'의 모든 기능을 포함하도록 로그 인쇄를 업데이트했습니다. 완전한 '읽기'세부 사항 은 /programming//a/10929511 을 참조 하십시오. EOF 검사는 여기에 필요하지 않지만 완전성을 위해 포함되어 있습니다.


아주 좋아요 while IFS= read -r LOGLINE에서 행이 공백으로 분할되는 것을 막기 위해을 사용하는 것이 tail좋습니다.
roaima

@roaima : read변수가 하나만있을 때 (그리고가 포함 된 배열이 아닌 경우) 분할되지 않지만 입력 데이터에 백 슬래시가 포함되어 있으면 -a필요 -r합니다. 입력 데이터가 백 슬래시를 포함한다면, 다음 echo "$var"도 그래서 더 쉘 및 / 또는 시스템에 따라 망칠 수있다printf '%s\n' "$line"
dave_thompson_085

@ dave_thompson_085 "IFS = read -r line"이해
roaima

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동일한 버퍼링을 수행하는 것처럼 보이므로 해결하려고 시도 할 가치가있는 것이 아닙니다.
aaronstacy

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.