我正在开发一个项目,在该项目中我需要从 bash shell 脚本对我的服务器之一进行 url 调用。
http://hostname.domain.com:8080/beat
点击上面的网址后,我将收到以下响应,我需要解析它并提取syncs
和 的值syncs_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
假设如果服务器关闭,则可能会出现失败的情况,然后wget
线路会引发异常。
现在我想做的是,如果服务器关闭,那么我将休眠 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”。但是,如果我在更新 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=
我猜这两个脚本是一样的?那么为什么会出现这样的情况呢?
答案1
您可以使用一个简单的循环:
....
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
....