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

后端 未结 5 1259
情话喂你
情话喂你 2020-12-29 08:39

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 printe
相关标签:
5条回答
  • 2020-12-29 08:45

    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);<>;"
    
    0 讨论(0)
  • 2020-12-29 09:00

    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
    
    0 讨论(0)
  • 2020-12-29 09:02
    #!/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.

    0 讨论(0)
  • 2020-12-29 09:02

    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)

    0 讨论(0)
  • 2020-12-29 09:06
    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
    
    0 讨论(0)
提交回复
热议问题