2012-09-13 214 views
2

我试图让shell脚本识别应用程序实例何时出现。这样它可以继续发布命令。循环外壳脚本,直到成功记录日志消息

我一直在想这将是这样的:

#/bin/bash 

startApp.sh 

while [ `tail -f server.log` -ne 'regex line indicating success' ] 
do 

sleep 5 

done 

echo "App up" 

但是,即使这个工作,它不会解决一些顾虑:

  • 如果有什么应用程序没有按” t会出现,它会等多久
  • 如果在将应用程序启动时出现错误怎么办
  • 如何捕获日志行并将其回显

我闭上了,还是有更好的办法?我想这是其他管理员不得不克服的问题。

编辑:

我发现这对超级用户

https://superuser.com/questions/270529/monitoring-a-file-until-a-string-is-found

tail -f logfile.log | while read LOGLINE 
do 
    [[ "${LOGLINE}" == *"Server Started"* ]] && pkill -P $$ tail 
done 

我这个唯一的问题是,它可能永远不会退出。有没有办法在最长时间内添加?

回答

4

好了第一个答案是接近,但没有考虑我以为一切都可能发生。

我适应从这个链接的代码:

Ending tail -f started in a shell script

这就是我想出了:

#!/bin/bash 

instanceDir="/usr/username/server.name" 
serverLogFile="$instanceDir/server/app/log/server.log" 

function stopServer() { 

    touch ${serverLogFile} 

    # 3 minute timeout. 
    sleep 180 & 
    local timerPid=$! 

    tail -n0 -F --pid=${timerPid} ${serverLogFile} | while read line 
    do 
     if echo ${line} | grep -q "Shutdown complete"; then 
      echo 'Server Stopped' 
      # stop the timer.. 
      kill ${timerPid} > /dev/null 2>&1 
     fi 
    done & 

    echo "Stoping Server." 
    $instanceDir/bin/stopserver.sh > /dev/null 2>&1 

    # wait for the timer to expire (or be killed) 
    wait %sleep 


} 

function startServer() { 

    touch ${serverLogFile} 

    # 3 minute timeout. 
    sleep 180 & 
    local timerPid=$! 

    tail -n0 -F --pid=${timerPid} ${serverLogFile} | while read line 
    do 
     if echo ${line} | grep -q "server start complete"; then 
      echo 'Server Started' 
      # stop the timer.. 
      kill ${timerPid} > /dev/null 2>&1 
     fi 
    done & 

    echo "Starting Server." 
    $instanceDir/bin/startserver.sh > /dev/null 2>&1 & 

    # wait for the timer to expire (or be killed) 
    wait %sleep 

} 

stopServer 
startServer 
+0

如果statup失败会发生什么? –

+0

嗯,这是旧的,但如果启动失败,你应该看到在控制台上,并按下ctrl-c退出。最终,--pid标志会看到睡眠过程在180秒内退出,并终止尾部,最终导致整个脚本退出。 – tpederson

2

那么,tail -f永远不会退出,所以这不是你想要的。

numLines=10 
timeToSleep=5 
until tail -n $numLines server.log | grep -q "$serverStartedPattern"; do 
    sleep $timeToSleep 
done 

确保$numLines比在$timeToSleep可能出现在服务器已经拿出线的数量。

这将永远持续;如果你想只允许这么多的时间,你可以把对循环迭代的次数上限像这样的东西:

let maxLoops=60 numLines=10 timeToSleep=5 success=0 
for ((try=0; try < maxLoops; ++try)); do 
    if tail -n $numLines server.log | grep -q "$serverStartedPattern"; then 
    echo "Server started!" 
    success=1 
    break 
    fi 
    sleep $timeToSleep 
done 

if ((success)); then 
    echo "Server started!" 
else 
    echo "Server never started!" 
fi 

exit $((1-success)) 
+0

我想过这个问题,我唯一担心的是,加载Java进程它的时候可以每秒输出数百行。因此,如果我将其设置得足够高以弥补这一点,那么它可能会捕获之前的重新启动并给出误报。 – tpederson