From da5d9339e2f8c3471636f07d3b3f41ad18c996e1 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Fri, 25 Sep 2026 05:43:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=8A=20PATH=20=E5=BD=92=E4=B8=80=E5=8C=96?= =?UTF-8?q?=E6=8F=90=E5=88=B0=E6=96=87=E4=BB=B6=E6=9C=80=E5=89=8D=EF=BC=88?= =?UTF-8?q?=E4=BF=AE=E6=88=91=2054d641e=20=E9=82=A3=E4=B8=AA"=E5=8F=AA?= =?UTF-8?q?=E4=BF=AE=E4=B8=80=E5=8D=8A"=E7=9A=84=E4=BF=AE=E6=B3=95?= =?UTF-8?q?=EF=BC=89=EF=BC=8C=E5=B9=B6=E6=8A=8A=20--help=20=E4=BB=8E?= =?UTF-8?q?=E6=95=B0=E8=A1=8C=E5=8F=B7=E6=94=B9=E6=88=90=E9=94=9A=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ★ 我上一版(54d641e)修了三条触发带,但**引入了第二个问题**(矩阵实测发现): 空 PATH / 最小 PATH 下: de1b072 rc=2("找不到 git"+人话,**符合**本仓环境词汇表) in-block rc=**128**("fatal: not in a git directory",**不在**词汇表) ⇒ 因为归一化仍在 `REPO=…dirname…`(line 11)**之后** ⇒ dirname 先失败 ⇒ REPO 退化成 / ⇒ ★ "修一处、坏一处":我把一处**符合约定的人话诊断**换成了**裸退出码** ★ 正确位置 = **文件最前**(env-defaults.sh:124 自己也注明 ④「**必须排在最前**」): 4 变体 × 6 种 PATH 矩阵(真 git worktree,工具齐全但 PATH 无 git): PATH old(^de1b072) de1b072 in-block(54d641e) final (空) 1/- 2/- 128/- **0/.githooks** 仅 bash/env 1/- 2/- 128/- **0/.githooks** /opt/tools 0/.githooks 2/- 0/.githooks **0/.githooks** /usr/local/sbin 0/.githooks 2/- 0/.githooks **0/.githooks** /sbin:/usr/sbin 0/.githooks 2/- 0/.githooks **0/.githooks** /usr/bin 0/.githooks 0/.githooks 0/.githooks **0/.githooks** ⇒ final 六行全绿;连跑两次幂等;`command -v git` 真失败时仍 exit 2 + 人话(负控制保留) ★ 顺带修一处**既存**脆弱点(被本次插入暴露,非本次引入): `--help` 原为 `sed -n '2,20p'`(**数行号**)⇒ 任何人往文件头插行都会让它开始印**实现代码** (原版就已经把 `set -euo pipefail`/`REPO=…` 印出来;插 PATH 块后会多印 5 行 case…esac) 改为 `usage()` = `sed -n '2,/^set -euo pipefail/p' | sed '$d'`(**锚定**) 实测: --help 7 行纯注释 ✓(原 19 行含代码);相对/绝对/符号链接三种调用都 rc=0 ✓ ★ 验证: bash -n OK;mode=755;mode gate 对 install.sh 零命中 ★ 边界: 只改 deploy/install.sh 一个文件;生产未动(仍 09-19 13:04) --- deploy/install.sh | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/deploy/install.sh b/deploy/install.sh index 040c1d5..15a2a03 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -8,8 +8,24 @@ # 因为里面有管理员密码与 Agent secret,重装不该把它们冲掉。 set -euo pipefail +# ⚠️⚠️ **PATH 归一化必须排在文件最前**(pi 2026-09-25 实测报回): +# 规则与 `lib/env-defaults.sh` 的 ④ 逐字相同(那里注明"**必须排在最前**",此处提前到 `dirname` 之前)。 +# 为什么非在这里不可:下面这行 `REPO=…dirname…` 是**本文件第一条外部命令**, +# PATH 缺 `/usr/bin` 时它先失败 ⇒ `REPO` 退化成 `/` ⇒ 后面即使找到 git 也会 +# `fatal: not in a git directory`(退出码 **128**,不在本仓"环境问题=2+人话"的词汇表里)。 +# 幂等:已含 `/usr/bin` 时一个字节都不改。 +case ":${PATH:-}:" in + *:/usr/bin:*) : ;; + *) PATH="${PATH:+$PATH:}/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; export PATH ;; +esac + REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +# 用法块 = 文件头注释。**锚定在 `set -euo pipefail` 上,不数行号** —— +# 原来写 `sed -n '2,20p'`,任何人往文件头插几行都会让 `--help` 开始印**实现代码** +# (本文件 2026-09-25 插 PATH 归一化时就会多印 5 行 `case … esac`)。锚定后插多少行都不漏。 +usage() { sed -n '2,/^set -euo pipefail/p' "$0" | sed '$d'; } + # ══════════════════════════════════════════════════════════════════════════════ # ./deploy/install.sh --check # 干跑:只跑所有门禁与前置检查,**不写系统目录** # @@ -34,7 +50,7 @@ for a in "$@"; do --allow-dirty) ALLOW_DIRTY=1 ;; --allow-stale) ALLOW_STALE=1 ;; --git-hooks) GIT_HOOKS=1 ;; - -h|--help) sed -n '2,20p' "$0"; exit 0 ;; + -h|--help) usage; exit 0 ;; *) echo "未知参数:$a(支持 --check / --allow-dirty / --allow-stale / --git-hooks)" >&2; exit 2 ;; esac done @@ -81,15 +97,9 @@ if [[ $GIT_HOOKS -eq 1 ]]; then # (这是我把本块前移时实测撞出来的:127 不在本仓的退出码词汇表里。) # # ⚠️⚠️ 但只补 ① 不够 —— 前移同时**丢掉了第二条**保证(pi 2026-09-25 实测报回:活回归): - # **env-defaults ④ 的 PATH 归一化**(PATH 可能不含 /usr/bin)。 - # 只补 ① 会得到**假红**:git 明明装在 /usr/bin,却因 PATH 里没有它而报"找不到 git", - # 且**真的没装上**(旧位置 rc=0 装上 / 前移后 rc=2 未装)。 - # ★ 这一条比 ① 更隐蔽:① 缺了是**漏**(少一条检查)② 缺了是**误**(凭空假红)。 - # 规则与 env-defaults.sh:124-130 的 ④ 逐字相同(且同样幂等)。 - case ":${PATH:-}:" in - *:/usr/bin:*) : ;; - *) PATH="${PATH:+$PATH:}/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; export PATH ;; - esac + # **env-defaults ④ 的 PATH 归一化**。本条现已在**文件最前**统一补回(见该处注释), + # 故这里不再重复。★ 两条的失败方向相反:① 缺了是**漏**(少一条检查), + # ② 缺了是**误**(git 装在 /usr/bin 却报"找不到 git",凭空假红)。 if ! command -v git >/dev/null 2>&1; then echo " [FAIL] 环境不足:找不到 git(--git-hooks 只用 git,但它不在 PATH 里)" >&2 echo " 药方:装 git,或把它的目录加进 PATH 后重跑。" >&2