- step_run 增加耗时统计(▶ 开始 / ✔ 完成 Ns / ✗ 失败 exit=N)与 STEP_LOG 支持 - domestic_full.sh / pipeline.sh 去掉 tail 截断,输出实时透传终端并 tee 到 logs/*.log - 退出码用 PIPESTATUS[0] 捕获(规避 pipefail/tee 吞码);全角标点后变量用花括号包裹 - 已同步 pi5 实测:M3 31s / M6 20s 耗时显示正常,日志文件生成
75 lines
2.8 KiB
Bash
75 lines
2.8 KiB
Bash
#!/bin/bash
|
||
# =============================================
|
||
# 步骤状态管理(--resume 中断恢复用)
|
||
# =============================================
|
||
# 用法(在脚本中 source):
|
||
# source "$SCRIPT_DIR/_step_state.sh"
|
||
# RESUME=0|1 # 由入口脚本参数解析后设置
|
||
# step_run <步骤名> <cmd...> # 执行并在成功后标记;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 在条件上下文(&&/||)调用函数时失效,
|
||
# 导致失败步骤被误标记为完成。
|
||
# 设置环境变量 STEP_LOG=路径 时,步骤全部输出同时写入该日志(终端仍实时显示)。
|
||
local name="$1"
|
||
shift
|
||
if ! step_should_run "$name"; then
|
||
return 0
|
||
fi
|
||
local t0 rc t1
|
||
t0=$(date +%s)
|
||
LOG "▶ $name 开始"
|
||
# 显式取原命令退出码(PIPESTATUS[0]):
|
||
# - 无 pipefail 时管道码=tee 码(0),必须用 PIPESTATUS 还原真实结果;
|
||
# - pipefail + 非条件上下文时失败会触发 set -e 直接退出(此时不 mark,正确);
|
||
# - 条件上下文调用时 set -e 被抑制,这里仍能正确捕获并 return。
|
||
if [ -n "${STEP_LOG:-}" ]; then
|
||
"$@" 2>&1 | tee -a "$STEP_LOG"
|
||
rc=${PIPESTATUS[0]}
|
||
else
|
||
"$@"
|
||
rc=$?
|
||
fi
|
||
t1=$(date +%s)
|
||
if [ "$rc" -ne 0 ]; then
|
||
LOG "✗ ${name} 失败(exit=${rc},耗时 $((t1 - t0))s);未标记完成,可 --resume 重试"
|
||
return "$rc"
|
||
fi
|
||
LOG "✔ $name 完成(耗时 $((t1 - t0))s)"
|
||
step_mark "$name"
|
||
}
|