5

I use this to check the log lines of a log file until the occurrence of a specific event (taken from this answer to Monitoring a file until a string is found):

(tail -f -n 0 test.log &) | grep -q 'SPEFICIC LOG MESSAGE'

This works, but I also want the log lines to be printed to stdout while waiting for the event. I am looking for something like tee, but I want to print and pipe at the same time.

I tried this answer to Pipe and watch piped output?, leading to:

(tail -f -n 0 test.log &) | tee /dev/fd/2 | grep -q 'SPEFICIC LOG MESSAGE'

but then the command never quits, presumably because grep fails to interrupt tail when it finds a match, so tail continues to deliver data to tee?

1 Answer 1

5

After grep exits, your tee will exit due to SIGPIPE only when it tries to write more to the pipe. This is how pipes work. This means you need one more line from tail. tee will exit eventually, unless tail is forever silent after printing SPEFICIC LOG MESSAGE.

tail … | grep … is similar in general. The trick with (tail … &) makes your main shell not wait for tail (it waits for the subshell instead, and the subshell does not wait for tail thanks to &).

You can use the same trick with tee:

(tail -f -n 0 test.log &) | (tee /dev/fd/2 &) | grep -q 'SPEFICIC LOG MESSAGE'

The main shell will wait for the two subshells and grep. The subshells will exit almost immediately, so it's grep what matters. When grep exits, the main shell will continue.

tee will stay in the background until it tries to write more. Only then it gets SIGPIPE and exits. This requires one extra line from the log.

In turn tail will stay in the background until it tries to write more after tee exits. This requires another extra line from the log. Unless your tail is smart. GNU tail detects broken pipe immediately, it does not require the trick. Using the trick with GNU tail is harmless, so when in doubt, use it.

tee is not that smart, it does require the trick.

The command I gave you should work, but keep in mind tee and tail will stay in the background until the next line appears in the log. If your tail is not smart then it will stay for yet another line.

3
  • Excellent explanation! Thank you! I had just copied the line form the other answer, which unfortunately does not explain what ( ... &) actually does (and I had no idea).
    – not2savvy
    Dec 10, 2022 at 14:52
  • 3
    wouldn't (tail -f -n 0 test.log | tee /dev/fd/2 &) | grep -q 'SPEFICIC LOG MESSAGE' work as well ?
    – Uriel
    Dec 10, 2022 at 22:25
  • @Uriel I think it would. Dec 10, 2022 at 22:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .