Как обрабатываете ошибки в bash-скриптах

«Как обрабатываете ошибки в bash-скриптах» — вопрос из категории Скриптинг и автоматизация, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В скриптах для автоматизации инфраструктуры надежная обработка ошибок критична. Я использую комбинацию строгих режимов, перехвата сигналов и явных проверок.

Базовые директивы для строгого режима: Добавляю в начало скрипта:

#!/usr/bin/env bash
set -euo pipefail
  • set -e (errexit): Немедленный выход при ошибке в любой команде (ненулевой код возврата).
  • set -u (nounset): Выход при попытке использования неинициализированной переменной.
  • set -o pipefail: Код возврата пайплайна считается неудачным, если ошиблась хотя бы одна команда в цепочке, а не только последняя.

Перехват сигналов и очистка (trap): Использую trap для гарантированного выполнения cleanup-действий (удаление временных файлов, откат изменений) даже при аварийном завершении.

#!/usr/bin/env bash
set -euo pipefail

TEMP_FILE="/tmp/myscript.$$"

cleanup() {
    exit_code=$?
    echo "Выполняется cleanup..." >&2
    rm -f "$TEMP_FILE"
    # Дополнительные действия: удаление временного namespace в k8s, отключение от VPN и т.д.
    exit $exit_code
}
# Срабатывает при EXIT, ошибке (ERR), прерывании (INT) и завершении (TERM)
trap cleanup EXIT ERR INT TERM

# Основная логика скрипта
if ! command -v jq > /dev/null; then
    echo "ОШИБКА: jq не установлен. Установите пакет jq." >&2
    exit 1
fi

config=$(cat config.json | jq '.settings') || {
    echo "Не удалось распарсить config.json" >&2
    exit 1
}

Практические примеры из DevOps:

  • Проверка доступности сервиса:
    if ! curl -sf --max-time 5 http://${SERVICE_URL}/health > /dev/null; then
        echo "Сервис ${SERVICE_URL} недоступен" >&2
        # Можно отправить алерт в Slack/PagerDuty
        exit 1
    fi
  • Работа с Terraform/AWS CLI:
    aws ec2 describe-instances --instance-ids "$INSTANCE_ID" > /dev/null 2>&1
    if [[ $? -ne 0 ]]; then
        echo "Инстанс ${INSTANCE_ID} не найден" >&2
        exit 1
    fi

    Логирование всех действий и ошибок в структурированном виде (например, JSON) упрощает дальнейший анализ в системах вроде ELK или Loki.