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

£可爱£侵袭症+ 提交于 2019-11-30 04:55:57
#!/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.

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

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)

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

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