![如何在脚本中编写重试逻辑以不断重试运行最多 5 次?](https://linux22.com/image/33844/%E5%A6%82%E4%BD%95%E5%9C%A8%E8%84%9A%E6%9C%AC%E4%B8%AD%E7%BC%96%E5%86%99%E9%87%8D%E8%AF%95%E9%80%BB%E8%BE%91%E4%BB%A5%E4%B8%8D%E6%96%AD%E9%87%8D%E8%AF%95%E8%BF%90%E8%A1%8C%E6%9C%80%E5%A4%9A%205%20%E6%AC%A1%EF%BC%9F.png)
我想在 shell 脚本中编写逻辑,该逻辑将根据以下条件在 15 秒后重试运行最多 5 次“状态代码=失败”如果由于某些问题而失败。
答案1
for i in 1 2 3 4 5; do command && break || sleep 15; done
将“命令”替换为您的命令。这是假设“状态代码=失败”意味着任何非零返回代码。
变化:
使用{..}
语法。适用于大多数 shell,但不适用于 BusyBox sh
:
for i in {1..5}; do command && break || sleep 15; done
使用seq
并传递失败命令的退出代码:
for i in $(seq 1 5); do command && s=0 && break || s=$? && sleep 15; done; (exit $s)
与上面相同,但sleep 15
在最终失败后跳过。由于最好只定义一次最大循环数,因此可以通过在循环开始时休眠来实现i > 1
:
for i in $(seq 1 5); do [ $i -gt 1 ] && sleep 15; command && s=0 && break || s=$?; done; (exit $s)
答案2
该脚本使用计数器n
将命令尝试次数限制为五次。如果命令成功,则break
结束循环。
n=0
until [ "$n" -ge 5 ]
do
command && break # substitute your command here
n=$((n+1))
sleep 15
done
答案3
function fail {
echo $1 >&2
exit 1
}
function retry {
local n=1
local max=5
local delay=15
while true; do
"$@" && break || {
if [[ $n -lt $max ]]; then
((n++))
echo "Command failed. Attempt $n/$max:"
sleep $delay;
else
fail "The command has failed after $n attempts."
fi
}
done
}
例子:
retry ping invalidserver
产生这个输出:
ping: unknown host invalidserver
Command failed. Attempt 2/5:
ping: unknown host invalidserver
Command failed. Attempt 3/5:
ping: unknown host invalidserver
Command failed. Attempt 4/5:
ping: unknown host invalidserver
Command failed. Attempt 5/5:
ping: unknown host invalidserver
The command 'ping invalidserver' failed after 5 attempts
有关使用复杂命令的真实工作示例,请参阅这个脚本。
答案4
这是重试的函数
function retry()
{
local n=0
local try=$1
local cmd="${@: 2}"
[[ $# -le 1 ]] && {
echo "Usage $0 <retry_number> <Command>"; }
until [[ $n -ge $try ]]
do
$cmd && break || {
echo "Command Fail.."
((n++))
echo "retry $n ::"
sleep 1;
}
done
}
retry $*
输出 :
[test@Nagios ~]$ ./retry.sh 3 ping -c1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.207 ms
--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.207/0.207/0.207/0.000 ms
[test@Nagios ~]$ ./retry.sh 3 ping -c1 localhostlasjflasd
ping: unknown host localhostlasjflasd
Command Fail..
retry 1 ::
ping: unknown host localhostlasjflasd
Command Fail..
retry 2 ::
ping: unknown host localhostlasjflasd
Command Fail..
retry 3 ::