Shell函数在特定时间内为特定string定尾日志文件

我需要以下的东西来确保我的应用程序服务器是

  1. 尾日志文件的特定string
  2. 保持阻止状态直到打印string
  3. 但是,如果string不打印大约20分钟,则退出并抛出exception消息,如“服务器花费了20分钟以上”
  4. 如果在日志文件中打印string,则退出循环并继续。

有没有办法在一个while循环中包含超时?

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

这读取任何写入日志文件,搜索certain_word,回声ok如果一切正常,否则等待1200秒(20分钟)后,它抱怨。

你可以这样做:

 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 

您可以使用shell脚本中的信号处理程序(请参阅http://www.ibm.com/developerworks/aix/library/au-usingtraps/index.html )。

基本上,你可以定义一个函数来调用信号17,然后在后台放置一个子脚本,稍后再发送该信号:

 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 

然后,如果你达到1200秒,你的功能被调用,你可以选择做什么(如信号你的尾巴/ grep组合正在观察你的模式,以杀死它)

 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 

被接受的答案是行不通的,因为在read -t退出时,先前的管道命令( tail -f | grep )只会在尝试写入输出时通知read -t退出,这从来没有发生直到字符串匹配)。

一行可能是可行的,但这里是脚本(工作)的方法。 每个逻辑都是一样的,他们使用kill来终止当前脚本超时之后。 Perl可能比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);<>;"