本文目录导读:

在Shell脚本中,有多种方式可以实现“循环执行直到成功”,以下是几种常见的方法:
使用 until 循环
#!/bin/bash
until command
do
echo "命令执行失败,重新尝试..."
sleep 1
done
echo "命令执行成功!"
使用 while 循环
#!/bin/bash
while ! command
do
echo "命令执行失败,重新尝试..."
sleep 1
done
echo "命令执行成功!"
限制重试次数
#!/bin/bash
max_retries=5
count=0
while ! command
do
count=$((count + 1))
if [ $count -ge $max_retries ]; then
echo "达到最大重试次数,退出..."
exit 1
fi
echo "重试第 $count 次..."
sleep 1
done
echo "命令执行成功!"
使用 curl 示例(检查URL是否可访问)
#!/bin/bash
while ! curl -s --head http://example.com > /dev/null 2>&1
do
echo "网站不可达,10秒后重试..."
sleep 10
done
echo "网站可以访问!"
带退出条件的版本
#!/bin/bash
max_attempts=10
attempt=1
while [ $attempt -le $max_attempts ]
do
if command; then
echo "命令在第 $attempt 次尝试后成功"
break
else
echo "第 $attempt 次尝试失败"
attempt=$((attempt + 1))
sleep 2
fi
done
if [ $attempt -gt $max_attempts ]; then
echo "所有重试都失败了"
exit 1
fi
使用函数封装
#!/bin/bash
retry() {
local max_retries=${2:-3}
local count=0
local sleep_time=${3:-2}
until "$@" || [ $count -eq $max_retries ]
do
count=$((count + 1))
echo "重试 $count/$max_retries..."
sleep $sleep_time
done
if [ $count -eq $max_retries ]; then
echo "命令 '$*' 在 $max_retries 次重试后仍然失败"
return 1
fi
}
# 使用示例
retry "ping -c 1 google.com" 5 3
retry "curl -s http://example.com" 3 2
添加指数退避(指数级增加等待时间)
#!/bin/bash
max_retries=5
count=0
wait_time=1
while ! command
do
count=$((count + 1))
if [ $count -ge $max_retries ]; then
echo "失败退出"
exit 1
fi
echo "等待 ${wait_time}秒后重试..."
sleep $wait_time
wait_time=$((wait_time * 2)) # 每次翻倍等待时间
done
echo "成功执行!"
带日志记录版本
#!/bin/bash
log_file="/var/log/command_retry.log"
timestamp() {
date "+%Y-%m-%d %H:%M:%S"
}
while ! command
do
echo "$(timestamp) 执行失败,正在重试..." >> $log_file
sleep 5
done
echo "$(timestamp) 执行成功" >> $log_file
使用建议:
- 避免无限循环:始终设置最大重试次数
- 添加延迟:使用
sleep避免频繁重试 - 记录日志:对于生产环境,记录重试信息便于调试
- 错误处理:确保重试失败时脚本能优雅退出
- 检查退出码:确保
command正确返回退出状态(成功返回0,失败返回非0)
这些方法可以根据具体需求灵活选择和组合使用。