Shell

在shell腳本中執行伺服器url時如何實現重試機制?

  • May 17, 2015

我正在開發一個項目,我需要從 bash shell 腳本對我的一台伺服器進行 url 呼叫。

http://hostname.domain.com:8080/beat

點擊上述網址後,我將得到以下響應,我需要對其進行解析並提取syncssyncs_behind

state: READY process: 30 process_behind: 100 num_rounds: 60 hour_col: 2 day_col: 0 oldest_day_col: 0

現在我需要在 10 分鐘內每 10 秒點擊一次上述 url 並從中提取和提取值,process然後process_behind使用它在以下條件下驗證它 -

process > 8
process_behind = 0

如果同步大於 8 並且 process_behind = 0,那麼我將以一些消息結束我的 shell 腳本 - “數據已被驗證”,否則我將繼續嘗試 10 分鐘視窗。如果在那 10 分鐘視窗中,不滿足上述條件無論如何我都會結束 shell 腳本,這意味著我不會再試一次。

下面是我的 shell 腳本,它執行上述操作,並且在伺服器啟動時正常工作。

#!/bin/bash

COUNT=60   #number of 10 second timeouts in 10 minutes

while [[ $COUNT -ge "0" ]]; do

#send the request, put response in variable
DATA=$(wget -O - -q -t 1 http://hostname.domain.com:8080/beat)

#grep $DATA for process and process_behind
PROCESS=$(echo $DATA | grep -oE 'process: [0-9]+' | awk '{print $2}')
PROCESS_BEHIND=$(echo $DATA | grep -oE 'process_behind: [0-9]+' | awk '{print $2}')

echo $PROCESS
echo $PROCESS_BEHIND

#verify conditionals
if [[ $PROCESS -gt "8" && $PROCESS_BEHIND -eq "0" ]]; then exit 0; fi

#decrement the counter
let COUNT-=1

#wait another 10 seconds
sleep 10

done

假設如果伺服器關閉,則可能會出現失敗的情況,然後wgetline 會引發異常。

現在我要做的是,如果伺服器關閉,那麼我將休眠 30 秒,然後再次重試執行伺服器 url,如果再次失敗,則再次休眠 30 秒,然後再次重試執行伺服器 url . 我將重試執行伺服器 url n 次,假設 n 為 10。

在那之後,伺服器仍然沒有啟動,我將以非零狀態退出 shell 腳本,並且消息伺服器已關閉。但是,如果伺服器啟動並且我能夠得到響應,我將繼續提取我在以後的 shell 腳本中擁有的那些欄位。

這可以在 bash shell 腳本中實現重試機制嗎?或者除了wget還有什麼更好的方法嗎?

更新1:-

這就是我得到的-

#!/bin/bash

COUNT=60   #number of 10 second timeouts in 10 minutes
DATA=""
RETRY=10

while [[ $COUNT -ge "0" ]]; do

while [ $RETRY -gt 0 ]
do
   #send the request, put response in variable
   DATA=$(wget -O - -q -t 1 http://machineA:8080/beat)
   echo "Hello"
   if [ $? -eq 0 ]
   then
       break
   else
       let RETRY-=1
       sleep 30
   fi
done

if [ $RETRY -eq 0 ]
then
   exit 2
fi

#grep $DATA for process and process_behind
PROCESS=$(echo $DATA | grep -oE 'process: [0-9]+' | awk '{print $2}')
PROCESS_BEHIND=$(echo $DATA | grep -oE 'process_behind: [0-9]+' | awk '{print $2}')

echo $PROCESS
echo $PROCESS_BEHIND

#verify conditionals
if [[ $PROCESS -gt "8" && $PROCESS_BEHIND -eq "0" ]]; then exit 0; fi

#decrement the counter
let COUNT-=1

#wait another 10 seconds
sleep 10

done

如果我的伺服器已關閉並且我正在執行上面的 shell 腳本,那麼它會在控制台上列印“Hello”並且它工作正常。但請參閱我的以下更新 -

更新 2:-

好的,現在我發現了問題,如果我正在執行這樣的 shell 腳本,我將在我的生產系統中執行並且如果伺服器關閉,那麼它根本不會列印出“Hello”。但是,如果我在 Update 1 中執行上述 shell 腳本並且伺服器已關閉,則它可以正常工作。

#!/bin/bash

COUNT=60   #number of 10 second timeouts in 10 minutes
HOSTNAME=machineA
DATA=""
RETRY=10

while [[ $COUNT -ge "0" ]]; do

while [ $RETRY -gt 0 ]
do
   #send the request, put response in variable
   DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
   echo "Hello"
   if [ $? -eq 0 ]
   then
       break
   else
       let RETRY-=1
       sleep 30
   fi
done

if [ $RETRY -eq 0 ]
then
   exit 2
fi

#grep $DATA for process and process_behind
PROCESS=$(echo $DATA | grep -oE 'process: [0-9]+' | awk '{print $2}')
PROCESS_BEHIND=$(echo $DATA | grep -oE 'process_behind: [0-9]+' | awk '{print $2}')

echo $PROCESS
echo $PROCESS_BEHIND

#verify conditionals
if [[ $PROCESS -gt "8" && $PROCESS_BEHIND -eq "0" ]]; then exit 0; fi

#decrement the counter
let COUNT-=1

#wait another 10 seconds
sleep 10

done

這就是我使用上述腳本在調試模式下得到的結果 -

david@some-machine:~$ bash -x ./ping1.sh
+ set -e
+ COUNT=60
+ HOSTNAME=machineA
+ DATA=
+ RETRY=10
+ echo machineA
machineA
+ [[ 60 -ge 0 ]]
+ '[' 10 -gt 0 ']'
++ wget -O - -q -t 1 http://machineA:8080/beat
+ DATA=

我猜這兩個腳本是一樣的?那為什麼會這樣呢?

您可以使用一個簡單的循環:

....
DATA=""
RETRY=10

while [ "$RETRY" -gt 0 ]; do
 DATA="$(wget -O - -q -t 1 http://hostname.domain.com:8080/beat)"
 if [ $? -eq 0 ]
 then
   break
 else
   let RETRY-=1
   sleep 30
 fi
done

if [ "$RETRY" -eq 0 ]
then
 exit 2
fi
....

引用自:https://unix.stackexchange.com/questions/126519