In general, if you don't necessarily know the process name, or just want to see if any process is accessing a file, you could try fuser
. For example, on Linux if I have a server process writing to server.log, then fuser server.log
gives something like:
/var/log/server.log: 28977
where 28977 is the process id of the server process. When the server process exits, fuser
returns nothing. Obviously in your case you also have the tail process reading the file, so you'd expect more than one PID, e.g.:
/var/log/server.log: 28977 28990
Note from the man page: "fuser outputs only the PIDs to stdout, everything else is sent to stderr.". So, for example, you could pipe to wc -w
and check you get at least 2
. Getting 1
would mean only your tail -f
was accessing the file.
The snag with integrating this in your loop is that read
will block until it can read a line, so any check you perform inside the loop will never be run once the file isn't being written to any longer. You'd need to use read -t
and specify a timeout. Something like this:
tail -f log_file | while [ 1 ]
do
read -t 10 LOGLINE
if [[ -z "${LOGLINE}" && $? -ne 0 ]] ; then
# Variable is empty and read timed out
if [[ `fuser log_file 2> /dev/null | wc -w` < 2 ]] ; then
# Nothing else is using the log file
pkill -f "tail -f log_file" # Specific, so we don't kill tails of other files
break
fi
else
echo -e "${LOGLINE}"
# Do your stuff...
fi
done
(thanks anubhava for reminding me of pkill! Also, note you could do a pgrep instead of the fuser check if you know enough identifying info about the process which is writing to the log.)
Another thing which would be much simpler if you're using Linux is to use the --pid
option for tail which will stop it if the process with that PID has stopped. Then you could just do:
LOG_WRITER=`pgrep something-identifying-the-process-writing-the-log`
tail -f log_file --pid=$LOG_WRITER | while read LOGLINE
…the rest of your script
However, it seems there may be cases in which this doesn't notice the process has stopped. It might be sufficient for you though.