🌀 Retry-логика в bash: как аккуратно повторять нестабильные операции
В админских скриптах не все ошибки означают, что все окончательно сломалось. Иногда команда падает из-за временной проблемы:
• сеть моргнула;
• API вернул timeout;
• DNS не ответил с первого раза;
• файл еще не появился;
• сервис еще не успел подняться;
• удаленный хост временно недоступен.
В таких случаях полезна retry-логика - аккуратный повтор операции несколько раз перед тем, как считать задачу проваленной.
🤩 Плохой вариант:
curl -fsS https://api.networkadmin.ru/deploy
Если запрос один раз упал - весь скрипт завершился.
🤩 Лучше сделать повтор:
for i in {1..5}; do
if curl -fsS https://api.networkadmin.ru/deploy; then
echo "success"
break
fi
echo "attempt $i failed, retrying..."
sleep 5
done
Но у такого варианта есть проблема: после всех неудачных попыток скрипт может продолжить работу, если явно не обработать итог.
🤩 Более аккуратный вариант - вынести retry в функцию:
retry() {
local max_attempts="$1"
local delay="$2"
shift 2
local attempt=1
until "$@"; do
if (( attempt >= max_attempts )); then
echo "command failed after $attempt attempts: $*" >&2
return 1
fi
echo "attempt $attempt failed, retrying in ${delay}s..." >&2
sleep "$delay"
((attempt++))
done
}
Теперь можно использовать так:
retry 5 3 curl -fsS https://api.networkadmin.ru/health
Или дождаться доступности сервиса:
retry 10 2 nc -z 127.0.0.1 5432
5 или 10 - количество попыток
3 или 2 - пауза между попытками
дальше идет команда, которую нужно повторять
▪️ Для операций с сетью часто полезен backoff - увеличение паузы после каждой ошибки:
retry_backoff() {
local max_attempts="$1"
local delay="$2"
shift 2
local attempt=1
until "$@"; do
if (( attempt >= max_attempts )); then
echo "command failed after $attempt attempts: $*" >&2
return 1
fi
echo "attempt $attempt failed, retrying in ${delay}s..." >&2
sleep "$delay"
delay=$((delay * 2))
((attempt++))
done
}
Пример:
retry_backoff 5 2 curl -fsS https://api.networkadmin.ru/status
Паузы будут примерно такими: 2s -> 4s -> 8s -> 16s
Это лучше, чем агрессивно долбить нестабильный сервис каждые 100 мс.
#bash #automation
🧑💻 NetworkAdmin
В админских скриптах не все ошибки означают, что все окончательно сломалось. Иногда команда падает из-за временной проблемы:
• сеть моргнула;
• API вернул timeout;
• DNS не ответил с первого раза;
• файл еще не появился;
• сервис еще не успел подняться;
• удаленный хост временно недоступен.
В таких случаях полезна retry-логика - аккуратный повтор операции несколько раз перед тем, как считать задачу проваленной.
🤩 Плохой вариант:
curl -fsS https://api.networkadmin.ru/deploy
Если запрос один раз упал - весь скрипт завершился.
🤩 Лучше сделать повтор:
for i in {1..5}; do
if curl -fsS https://api.networkadmin.ru/deploy; then
echo "success"
break
fi
echo "attempt $i failed, retrying..."
sleep 5
done
Но у такого варианта есть проблема: после всех неудачных попыток скрипт может продолжить работу, если явно не обработать итог.
🤩 Более аккуратный вариант - вынести retry в функцию:
retry() {
local max_attempts="$1"
local delay="$2"
shift 2
local attempt=1
until "$@"; do
if (( attempt >= max_attempts )); then
echo "command failed after $attempt attempts: $*" >&2
return 1
fi
echo "attempt $attempt failed, retrying in ${delay}s..." >&2
sleep "$delay"
((attempt++))
done
}
Теперь можно использовать так:
retry 5 3 curl -fsS https://api.networkadmin.ru/health
Или дождаться доступности сервиса:
retry 10 2 nc -z 127.0.0.1 5432
5 или 10 - количество попыток
3 или 2 - пауза между попытками
дальше идет команда, которую нужно повторять
▪️ Для операций с сетью часто полезен backoff - увеличение паузы после каждой ошибки:
retry_backoff() {
local max_attempts="$1"
local delay="$2"
shift 2
local attempt=1
until "$@"; do
if (( attempt >= max_attempts )); then
echo "command failed after $attempt attempts: $*" >&2
return 1
fi
echo "attempt $attempt failed, retrying in ${delay}s..." >&2
sleep "$delay"
delay=$((delay * 2))
((attempt++))
done
}
Пример:
retry_backoff 5 2 curl -fsS https://api.networkadmin.ru/status
Паузы будут примерно такими: 2s -> 4s -> 8s -> 16s
Это лучше, чем агрессивно долбить нестабильный сервис каждые 100 мс.
#bash #automation
🧑💻 NetworkAdmin