#!/bin/bash # ============================================= # 步骤状态管理(--resume 中断恢复用) # ============================================= # 用法(在脚本中 source): # source "$SCRIPT_DIR/_step_state.sh" # RESUME=0|1 # 由入口脚本参数解析后设置 # step_run <步骤名> # 执行并在成功后标记;resume 时已标记则跳过 # step_should_run <名> # 返回 0 = 需要运行(供需容忍部分失败的步骤手动控制) # step_mark <名> # 手动标记完成 # ============================================= # 状态文件: data/run_state/{YYYYMMDD}.state(按本地日期换新,跨天自动失效) # 说明: 各步骤内部的"跳过已处理文件"由各 Python 模块自带(见 pipeline.sh 头注释), # 本文件仅做"步骤级"断点记录。 # ============================================= STEP_STATE_DIR="data/run_state" step_state_file() { echo "${STEP_STATE_DIR}/$(date +%Y%m%d).state" } step_done() { # $1: 步骤名;已标记返回 0 [ -f "$(step_state_file)" ] && grep -qx "$1" "$(step_state_file)" >/dev/null 2>&1 } step_mark() { # $1: 步骤名;记录为已完成(幂等追加) mkdir -p "${STEP_STATE_DIR}" echo "$1" >> "$(step_state_file)" } step_should_run() { # $1: 步骤名;resume 模式下已标记 → 返回 1(跳过),否则返回 0 if [ "${RESUME:-0}" = "1" ] && step_done "$1"; then LOG "⏭️ 跳过已完成的步骤: $1(--resume)" return 1 fi return 0 } step_run() { # $1: 步骤名,$2...: 要执行的命令(成功后标记完成) # 显式检查退出码:避免 bash set -e 在条件上下文(&&/||)调用函数时失效, # 导致失败步骤被误标记为完成。 local name="$1" shift if ! step_should_run "$name"; then return 0 fi LOG "▶ $name" "$@" local rc=$? if [ "$rc" -ne 0 ]; then LOG "✗ $name 失败(exit=$rc),未标记完成;可 --resume 重试该步骤" return "$rc" fi step_mark "$name" }