Timeout Wrapper Command Execution

Bound external commands with the timeout utility, distinguishing exit code 124 from genuine failures and retrying on it.

BashResilience

Code

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

readonly TIMEOUT_SECS=30
readonly MAX_RETRIES=2

run_with_timeout() {
  local label="$1"
  shift

  local attempt=1
  while (( attempt <= MAX_RETRIES + 1 )); do
    timeout --kill-after=5s "${TIMEOUT_SECS}s" "$@" </dev/null
    local code=$?

    case "${code}" in
      0)
        echo "${label}: 成功"
        return 0
        ;;
      124)
        echo "Error: ${label} 第 ${attempt} 次超时(${TIMEOUT_SECS}s)" >&2
        (( attempt++ )) || true
        ;;
      137)
        echo "Error: ${label} 被强杀(TERM 后 5s 未退出)" >&2
        return 137
        ;;
      *)
        echo "Error: ${label} 失败,退出码 ${code}" >&2
        return "${code}"
        ;;
    esac
  done
  echo "Error: ${label} 超时重试耗尽" >&2
  return 124
}

# 用法:超时会重试,其他失败立即上抛
run_with_timeout "数据库迁移" ./migrate.sh --dry-run
run_with_timeout "健康探测" curl -sf http://127.0.0.1:8080/healthz