15

我需要做以下事情来确保我的应用程序服务器是

  1. 跟踪特定字符串的日志文件
  2. 在打印该字符串之前保持阻塞状态
  3. 但是,如果字符串在大约 20 分钟内未打印,则退出并抛出异常消息,例如“服务器需要超过 20 分钟才能启动”
  4. 如果在日志文件中打印了字符串,则退出循环并继续。

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

4

5 回答 5

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

这会读取写入日志文件的任何内容,搜索某些单词,如果一切正常,则回显 ok,否则在等待 1200 秒(20 分钟)后它会抱怨。

于 2012-12-21T02:48:39.773 回答
1

您可以使用来自 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 秒,您的函数将被调用,您可以选择要执行的操作(例如向您的 tail/grep 组合发出信号,该组合正在监视您的模式以杀死它)

于 2012-12-21T02:44:58.693 回答
1

你可以这样做:

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
于 2012-12-21T02:46:06.490 回答
0
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
于 2012-12-21T02:49:48.177 回答
0

接受的答案不起作用并且永远不会退出(因为尽管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 "$FILE" | grep "$MATCH" | (read -t 1 a ; kill $$)

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

# Uses perl & alarm signal
#tail -f "$FILE" | grep "$MATCH" | perl -e "\$SIG{ALRM} = sub { `kill $$`;exit; };alarm(1);<>;"
于 2017-08-31T07:52:21.177 回答