【发布时间】:2012-12-21 02:39:58
【问题描述】:
我需要做以下事情来确保我的应用服务器是
- 跟踪特定字符串的日志文件
- 在打印该字符串之前保持阻塞
- 但是,如果字符串在大约 20 分钟内未打印,则退出并抛出异常消息,例如“服务器需要超过 20 分钟才能启动”
- 如果日志文件中打印了字符串,则退出循环并继续。
有没有办法在 while 循环中包含超时?
【问题讨论】:
我需要做以下事情来确保我的应用服务器是
有没有办法在 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
【讨论】:
grep -F 用于固定字符串。
您可以使用 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 组合发出信号以杀死它)
【讨论】:
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
【讨论】:
sleep 1以外的指令也会占用执行时间。
接受的答案不起作用并且永远不会退出(因为尽管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);<>;"
【讨论】: