From 999ad924ad5722e073d166e6b8f0fe611378f55c Mon Sep 17 00:00:00 2001 From: jack Date: Fri, 28 Aug 2026 17:45:48 +0800 Subject: [PATCH] =?UTF-8?q?install.sh=20=E6=8A=A5=E5=87=BA=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E6=96=B0=E5=A2=9E=E7=9A=84=E9=85=8D=E7=BD=AE=E9=A1=B9?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E7=BB=99=20--sync-env=20=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit live.env 装着密钥,所以安装时刻意不覆盖。但这样一来,往 live.env.example 里加配置,已有部署会永远拿不到、且毫无提示——静默漂移,等到某个开关根本 没生效才发现。这次加 TG_TOKEN 就撞上了。 现在重复安装会 diff 两边的变量名:报模板多出的项(提示跑 --sync-env), 也报配置里已被模板删掉的项(可能已废弃)。 --sync-env 独立成一个模式而不是塞进安装流程:追加要改一个装着密钥的文件, 这种事应当由人显式发起。只追加缺的项、连它上面的注释一起,不动已有任何 一行,先备份。实测原有内容逐行未变且重复跑幂等。 Co-authored-by: Cursor --- live/deploy/install.sh | 63 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/live/deploy/install.sh b/live/deploy/install.sh index d9a4bef..b127c40 100755 --- a/live/deploy/install.sh +++ b/live/deploy/install.sh @@ -22,6 +22,51 @@ say() { echo " $*"; } [[ $EUID -eq 0 ]] || die "要 root:sudo $0" +# ── --sync-env:把模板新增的项追加到已有配置 ──────────────────────── +# 独立成一个模式而不是塞进安装流程:追加会改一个装着密钥的文件,这种事应当 +# 由你显式发起。只追加缺的项(连它上面的注释一起),**不动**已有任何一行。 +if [[ "${1:-}" == "--sync-env" ]]; then + EX="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/live.env.example" + [[ -f "$EX" ]] || die "找不到模板 $EX" + [[ -f "$CONF/live.env" ]] || die "$CONF/live.env 还不存在,先跑一次 sudo $0" + cp -a "$CONF/live.env" "$CONF/live.env.bak.$(date +%Y%m%d%H%M%S)" + python3 - "$EX" "$CONF/live.env" <<'PY' +import re +import sys + +ex_path, live_path = sys.argv[1], sys.argv[2] +ex = open(ex_path, encoding="utf-8").read().splitlines() +live = open(live_path, encoding="utf-8").read() +KEY = re.compile(r"^([A-Z_][A-Z0-9_]*)=") +have = set(KEY.match(x).group(1) for x in live.splitlines() if KEY.match(x)) + +add, block = [], [] +for line in ex: + if KEY.match(line): + k = KEY.match(line).group(1) + if k not in have: + add += block + [line] + block = [] + elif line.startswith("#") or (not line.strip() and block): + block.append(line) + else: + block = [] + +if not add: + print(" 配置已是最新,无需追加") + raise SystemExit(0) +with open(live_path, "a", encoding="utf-8") as f: + f.write("\n\n# ── 以下由 install.sh --sync-env 追加 ──\n") + f.write("\n".join(add) + "\n") +n = sum(1 for x in add if KEY.match(x)) +print(f" 追加了 {n} 项:" + + " ".join(KEY.match(x).group(1) for x in add if KEY.match(x))) +PY + say "原文件已备份为 $CONF/live.env.bak.*" + say "追加的项多半是空值,逐项填完再重启:sudo systemctl restart chan-live-exec" + exit 0 +fi + # ── 1. 系统依赖 ──────────────────────────────────────────────────── say "装系统包" if command -v apt-get >/dev/null; then @@ -104,7 +149,23 @@ if [[ ! -f "$CONF/live.env" ]]; then "$APP/live/deploy/live.env.example" "$CONF/live.env" NEED_FILL=1 else - say "$CONF/live.env 已存在,不动" + say "$CONF/live.env 已存在,不覆盖(里面是密钥)" + # 但要报出模板新增的项。不报的话,以后往 example 里加配置,已有部署会 + # **永远拿不到且毫无提示**——静默漂移,等到出事才发现某个开关根本没生效 + keys() { grep -oE '^[A-Z_][A-Z0-9_]*=' "$1" | tr -d '=' | sort -u; } + MISSING="$(comm -23 <(keys "$APP/live/deploy/live.env.example") \ + <(keys "$CONF/live.env") | tr '\n' ' ')" + if [[ -n "${MISSING// }" ]]; then + say "⚠ 模板比你的配置多了这些项:$MISSING" + say " 逐项看说明:$APP/live/deploy/live.env.example" + say " 要把缺的那几行连注释一起追加过去,跑:" + say " sudo $APP/live/deploy/install.sh --sync-env" + NEED_FILL=1 + fi + OBSOLETE="$(comm -13 <(keys "$APP/live/deploy/live.env.example") \ + <(keys "$CONF/live.env") | tr '\n' ' ')" + [[ -n "${OBSOLETE// }" ]] && \ + say " 另有模板里已没有的项(可能已废弃):$OBSOLETE" fi # ── 6. systemd ────────────────────────────────────────────────────