tags:

views:

147

answers:

2

Hi all, I have this bash script whose job is to monitor a log file for the occurrence of a certain line. When located, the script will send out an email warning and then terminate itself. For some reason, it keeps on running. How can I be sure to terminate bash script below:

#!/bin/sh

tail -n 0 -f output.err | grep --line-buffered "Exception" | while read line
do
    echo "An exception has been detected!" | mail -s "ALERT" [email protected]
    exit 0
done
+5  A: 

You are opening a subshell in the while read and that subshell is who is exiting, not the proper one.

Try before entering the while loop:

SHELLPID=$$

And then in the loop:

kill $SHELLPID
exit 0

Or change your loop to not use a subshell.

Since the parent script is always going to be in the tail -f which never ends I think you have no other choice than killing it from the inner subshell.

Arkaitz Jimenez
That didn't work. $PPID returns the starting PID (the shell instance that I'm running the script from). Any way to rewrite the script w/out the while loop?
Daniil
Check the update. In the end you still need a subshell because a process needs to be waiting for the tail while other checks the output.
Arkaitz Jimenez
That worked perfectly! Big thanks :)
Daniil
nit: the parent is not in tail -f. each process of the pipe is being executed as a separate subprocess, and the parent script is waiting for all of them.
William Pursell
You don't need to save `$$` to another variable. It doesn't change in the subshell (at least under these circumstances).
Dennis Williamson
@Dennis I would expect $$ to be different for the subshell, as it is another process, $$ will return another PID
Arkaitz Jimenez
A: 

Try something like this:

tail -n 0 -f output.err | grep --line-buffered "Exception" | while read line
do
    echo "An exception has been detected!" | mail -s "ALERT" [email protected]
    kill -term `ps ax | grep tail | grep output.err | awk '{print $1}'`
done

This should work, provided you have only one tail keeping an eye on this particular file.

Roman
That's overkill (no pun intended).
Dennis Williamson