#!/usr/bin/env bash # # 部署脚本的**环境自足**声明:一处给全,不再每条命令旁各写一个预检。 # # # 为什么要有这个文件 # # 2026-09-14 这条链上一共修了**四次**同一形状的错,每次形态一模一样: # **部署路径上假设了一个环境变量存在**。四次都是"再加一个预检", # 而预检只挡**已知的那一个** —— 挡住 `HOME` 之后 `GOMODCACHE` 才露出来 # (两者其实是同一个根因的两面:`HOME` 决定 go 默认缓存位置)。 # pi 的原话:**"否则第五次一定会来。"** # # 四次记录(每次都是实测,不是推测): # 1. `HOME` 未设 ⇒ `go` 拒绝工作(`homeagent` 的 build.sh,当次修了一处) # 2. `HOME` 未设 ⇒ 同一族再现(`install.sh`,当次又修一处) # 3. `TMPDIR` 未设/不可写 ⇒ 构建与测试把临时文件写到意外位置 # (`redeploy-plugin.sh:160` 曾写成 `TMPDIR=${TMPDIR:-/tmp} npx tsc …`,即就地兜了一次) # 4. `GOMODCACHE`/`GOPATH` 都未设(`HOME` 也没设)⇒ # `go: module cache not found: neither GOMODCACHE nor GOPATH is set` # # # 纪律 # # · 需要环境的脚本**开头** `source` 本文件,别在命令行里内联兜底; # · 本文件只设**未设**的变量(`:-` 语义),绝不覆盖调用者已经给的值; # · 失败要**说清是环境问题**并按仓库约定用退出码 2(环境),不要让它冒充代码缺陷。 # # 注意:本文件被 `source`,**不能带 `set -e`**(那会改调用者的语义)。 # 调用者自己已经有 `set -uo pipefail`(`install.sh` 另有 `-e`),这里不重复声明。 # shellcheck shell=bash # ① HOME:`go`/`npm`/`npx` 都会用它推默认缓存与配置位置。 # 以 root 跑部署时它通常就是 /root;显式给出以免"沙箱/最小环境下 HOME 为空"。 if [ -z "${HOME:-}" ]; then HOME=/root export HOME AGENTMAIL_ENV_DEFAULTS="${AGENTMAIL_ENV_DEFAULTS:-} HOME=$HOME" fi # ② TMPDIR:构建暂存与测试都往这里写。缺省 /tmp 可能与真实挂载不符, # 但"空的 TMPDIR"比"指错一个已存在的目录"更糟 —— 后者会让判据看错地方。 if [ -z "${TMPDIR:-}" ]; then TMPDIR=/tmp export TMPDIR AGENTMAIL_ENV_DEFAULTS="${AGENTMAIL_ENV_DEFAULTS:-} TMPDIR=$TMPDIR" fi # ③ GOMODCACHE / GOPATH:go 的模块缓存。**只在 go 存在时**推导, # 且只在两者都空的时候推导(有 GOPATH 时 go 自己会算 GOMODCACHE)。 if command -v go >/dev/null 2>&1; then if [ -z "${GOMODCACHE:-}" ] && [ -z "${GOPATH:-}" ]; then GOPATH="$HOME/go" export GOPATH AGENTMAIL_ENV_DEFAULTS="${AGENTMAIL_ENV_DEFAULTS:-} GOPATH=$GOPATH" fi fi # ④ PATH:只保证常见系统目录在(最小环境里 PATH 可能为空)。 case ":${PATH:-}:" in *:/usr/bin:*) : ;; *) PATH="${PATH:+$PATH:}/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; export PATH AGENTMAIL_ENV_DEFAULTS="${AGENTMAIL_ENV_DEFAULTS:-} PATH=+系统目录" ;; esac # 给调用者一句可打印的话:本次**兜了哪几个**变量(空则说明环境本来就齐)。 export AGENTMAIL_ENV_DEFAULTS="${AGENTMAIL_ENV_DEFAULTS:-}"