2012-09-13 463 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