Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've got a CI server with a command-line interface that allows me to remotely kick-off a job (jenkins CI server and the jenkins-cli.jar tool).

After I kick the job off I tail -f the log (sorry for the messy command):

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\""

After the job successfully completes, usually after at least 5 minutes, I get the following line on the output:

Finished: SUCCESS

Is there a good way to stop tailing the log at this point? i.e. is there like a tail_until 'some line' my-file.log command?

BONUS: extra credit if you can supply an answer that returns 0 when SUCCESS is matched, 1 when FAILURE is matched, and your solution works on mac! (which i believe is bsd based)

share|improve this question

4 Answers 4

up vote 13 down vote accepted

You can pipe the tail -f into sed, telling it to quit when it sees the line you're searching for:

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

sed will output each line it processes by default, and exit after it sees that line. The tail process will stop when it tries to write the next line and sees its output pipe is broken

share|improve this answer
    
booh yea! perfect. ...so by any chance is there a way to exit 0 if i match one thing (say 'SUCCESS') and 1 if i match something else (like maybe 'FAILURE')? –  aaronstacy Aug 20 '12 at 21:12
2  
@aaronstacy If you're using GNU grep, the q command takes an optional exit code. So the sed command would be sed '/^Finished: SUCCESS$/ q0; /^Finished: FAILURE$/ q1' –  Michael Mrozek Aug 20 '12 at 21:14
1  
This might not work if Finished: SUCCESS is the last line of output –  lk- Aug 20 '12 at 21:15
    
@Michael Mrozek aaaand of course i'm not b/c i'm using friggin mac –  aaronstacy Aug 20 '12 at 21:16
tail -f my-file.log | grep -qx "Finished: SUCCESS"

-q, meaning quiet, quits as soon as it finds a match

-x makes grep match the whole line

For the second part, try

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

-m <number> tells grep to stop after number matches

and the grep -q exit status will only be 0 if SUCCESS is found at the end of the line

If you want to see all the output, you can't use grep -q, but you can still do

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

which does everything except set the exit status to 1 if FAILURE appears.

share|improve this answer
1  
I used grep in my answer originally, but if he's using tail -f he probably wants to see the file output; grep isn't going to show all the intermediate lines –  Michael Mrozek Aug 20 '12 at 22:36

A variation on @Mikel's answer with @Mrozek's comments (I would have replied on the comment but I think i don't have enough privileges yet)

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

would allow you to use @Mikel's solution and still see the output on the screen

share|improve this answer

here's a python script that almost does what i want (see caveats below):

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()

caveats:

  • the lines aren't printed as they come in... they're printed in groups... seems to be some buffering going on

  • i'd have to install this as a script on my path or something, so it's inconvenient, and i'd prefer a slick one-liner :)

share|improve this answer
    
update: tail seems to do the same buffering, so i'm guessing it's not something that's worth trying to work around. –  aaronstacy Aug 20 '12 at 21:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.