Shell function to tail a log file for a specific string for a specific time

核能气质少年 提交于 2019-11-27 14:01:01

问题


I need to the following things to make sure my application server is

  1. Tail a log file for a specific string
  2. Remain blocked until that string is printed
  3. However if the string is not printed for about 20 mins quit and throw and exception message like "Server took more that 20 mins to be up"
  4. If string is printed in the log file quit the loop and proceed.

Is there a way to include time outs in a while loop ?


回答1:


#!/bin/bash
tail -f logfile | grep 'certain_word' | read -t 1200 dummy_var
[ $? -eq 0 ]  && echo 'ok'  || echo 'server not up'

This reads anything written to logfile, searches for certain_word, echos ok if all is good, otherwise after waiting 1200 seconds (20 minutes) it complains.




回答2:


You can do it like this:

start_time=$(date +"%s")
while true
do
    elapsed_time=$(($(date +"%s") - $start_time))
    if [[ "$elapsed_time" -gt 1200 ]]; then
        break
    fi
    sleep 1
    if [[ $(grep -c "specific string" /path/to/log/file.log) -ge 1 ]]; then
        break
    fi
done



回答3:


You can use signal handlers from shell scripts (see http://www.ibm.com/developerworks/aix/library/au-usingtraps/index.html).

Basically, you'd define a function to be called on, say, signal 17, then put a sub-script in the background that will send that signal at some later time:

timeout(pid) {
   sleep 1200
   kill -SIGUSR1 $pid
}

watch_for_input() {
   tail -f file | grep item
}

trap 'echo "Not found"; exit' SIGUSR1
timeout($$) &
watch_for_input

Then if you reach 1200 seconds, your function is called and you can choose what to do (like signal your tail/grep combo that is watching for your pattern in order to kill it)




回答4:


time=0
found=0
while [ $time -lt 1200 ]; do
  out=$(tail logfile)
  if [[ $out =~ specificString ]]; then
    found=1
    break;
  fi  
  let time++
  sleep 1
done
echo $found



回答5:


The accepted answer doesn't work and will never exit (because althouth read -t exits, the prior pipe commands (tail -f | grep) will only be notified of read -t exit when they try to write to output, which never happens until the string matches).

A one-liner is probably feasible, but here are scripted (working) approaches. Logic is the same for each one, they use kill to terminate the current script after the timeout. Perl is probably more widely available than gawk/read -t

#!/bin/bash

FILE="$1"
MATCH="$2"

# Uses read -t, kill after timeout
#tail -f "$F" | grep "$MATCH" | (read -t 1 a ; kill $$)

# Uses gawk read timeout ability (not available in awk)
#tail -f "$F" | grep "$MATCH" | gawk "BEGIN {PROCINFO[\"/dev/stdin\", \"READ_TIMEOUT\"] = 1000;getline < \"/dev/stdin\"; system(\"kill $$\")}"

# Uses perl & alarm signal
#tail -f "$F" | grep "$MATCH" | perl -e "\$SIG{ALRM} = sub { `kill $$`;exit; };alarm(1);<>;"


来源:https://stackoverflow.com/questions/13983572/shell-function-to-tail-a-log-file-for-a-specific-string-for-a-specific-time

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!