#!/usr/bin/env bash set -euo pipefail project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" sql_path="${project_root}/database/mysql.sql" container_name="${1:-${ZBT_MYSQL_CONTAINER:-zhibaotong-mysql}}" container_sql_path="/tmp/zbt-init.sql" [[ -f "$sql_path" ]] || { echo "错误:缺少数据库快照 $sql_path" >&2 exit 1 } command -v docker >/dev/null 2>&1 || { echo "错误:未找到 Docker 命令,请先安装并启动 Docker Desktop。" >&2 exit 1 } docker inspect "$container_name" >/dev/null 2>&1 || { echo "错误:未找到 MySQL 容器 $container_name,可将实际容器名作为第一个参数传入。" >&2 exit 1 } if [[ "$(docker inspect --format '{{.State.Running}}' "$container_name")" != "true" ]]; then docker start "$container_name" >/dev/null fi # 首次创建 MySQL 容器时会经历“临时实例初始化 -> 正式实例启动”。 # 要求连续多次响应,避免命令落在两次启动之间。 ready=false consecutive_successes=0 for _ in $(seq 1 90); do if docker exec "$container_name" sh -c 'mysqladmin ping -uroot -p"$MYSQL_ROOT_PASSWORD" --silent >/dev/null 2>&1'; then consecutive_successes=$((consecutive_successes + 1)) if (( consecutive_successes >= 5 )); then ready=true break fi else consecutive_successes=0 fi sleep 1 done if [[ "$ready" != "true" ]]; then echo "MySQL 容器 $container_name 在 90 秒内未就绪。" >&2 exit 1 fi cleanup() { docker exec "$container_name" rm -f "$container_sql_path" >/dev/null 2>&1 || true } trap cleanup EXIT docker cp "$sql_path" "${container_name}:${container_sql_path}" docker exec "$container_name" sh -c \ 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" --default-character-set=utf8mb4 < /tmp/zbt-init.sql' echo "第二阶段 MySQL 数据初始化完成。"