I am implementing monitor_log
function which will tail the most recent line from running log and check required string with while loop, the timeout logic should be when the tail log running over 300 seconds, it must close the tail and while loop pipeline. Refer to How to timeout a tail pipeline properly on shell, as mentioned even monitor_log
function finished, it will left tail
process on background, so I have to manually kill it in case of hundreds times calling monitor_log
will left hundreds of tail
process.
The function monitor_log
below kill correct tail
PID only under single process situation, because tail_pid=$(ps -ef | grep 'tail' | cut -d' ' -f5)
will return the correct tail
PID which on the only process. When comes to multiple process situation(process fork), for example, multiple calls of monitor_log
function to parallel tail log, there will be multiple tail
process running, tail_pid=$(ps -ef | grep 'tail' | cut -d' ' -f5)
not able to return exactly tail
PID which belong to current fork.
So is that possible to NOT left tail
process when monitor_log
function finished ? OR if left tail
process, is there a proper way to find its correct PID (not the tail
PID from other thread) and kill it under multiple process situation ?
function monitor_log() {
if [[ -f "running.log" ]]; then
# Tail the running log last line and keep check required string
while read -t 300 tail_line
do
if [[ "$tail_line" == "required string" ]]; then
capture_flag=1
fi
if [[ $capture_flag -eq 1 ]]; then
break;
fi
done < <(tail -n 1 -f "running.log")
# Not get correct tail PID under multiple process
tail_pid=$(ps -ef | grep 'tail' | cut -d' ' -f5)
kill -13 $tail_pid
fi
}
You may try below code:
function monitor_log() {
if [[ -f "running.log" ]]; then
# Tail the running log last line and keep check required string
while read -t 300 tail_line
do
if [[ "$tail_line" == "required string" ]]; then
capture_flag=1
fi
if [[ $capture_flag -eq 1 ]]; then
break;
fi
done < <(tail -n 1 -f "running.log")
tailpid=$!
kill $tailpid
fi
}
> $! Gives the Process ID (PID) of last job run in background
Update: This would kill the subshell which triggers the tail as suggested in comment
Another way might be add timeout to the tail command as below:
timeout 300s tail -n 1 -f "running.log"