ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

rea 安装方式对比:curl 脚本与 npm 全局安装及排障

rea 安装方式对比:curl 脚本与 npm 全局安装及排障

rea 这个命令我在本地开发机、内网服务器、还有几个 CI 容器镜像里都装过,前后折腾了七八次,curl 脚本和 npm 全局安装这两条路都走过,也都在上面栽过跟头。最惨的一次是在一台没有外网直连的机器上,用 npm 装完显示成功,敲rea --version直接报“找不到命令”,排查了四十分钟才定位到是全局 bin 目录压根没进 PATH;还有一次更冤,两条路各装了一遍,结果机器上同时躺着两份不同版本的 rea,跑出来的结果对不上,日志看了半天才发现调用的不是同一个二进制。所以这篇不打算写成“官方安装文档的搬运”,而是把这两种安装方式拆到骨头上讲清楚:它们各自在文件系统里动了什么、为什么会有这种差异、什么样的机器该选哪条路、装完跑不起来的时候按什么顺序排查。如果你刚接触这个命令行工具,或者被“装是装上了但就是用不了”折磨过,下面这些内容基本能覆盖你 90% 的场景;如果你已经能熟练安装,那么第 4 节的横向对比表和第 5 节的排查链路,应该还能帮你省下几次重复劳动。

1. 装 rea 之前先想清楚:你到底在装什么

1.1 一条安装命令背后其实是四样东西

很多人把“安装 rea 命令”理解成“把一个文件放到某个地方”,这个理解只对了一半。真正落地到磁盘上,一次完整的安装至少要处理四件事,任何一件没做对,都会表现为“命令找不到”或者“命令能跑但行为异常”。

第一是可执行本体。它可能是编译好的平台相关二进制文件,也可能是打包过的 JS 入口脚本。前者绑定 CPU 架构和运行时库,比如 x86_64 与 arm64 是两个完全不同的产物,glibc 环境和 musl 环境(常见于精简容器镜像)也不能混用;后者则依赖机器上已经存在 Node.js 解释器。

第二是依赖。curl 脚本分发的方式,通常会把运行时依赖一起打进产物里做成自包含形态,装完就是一个目录或一个文件,拷走就能用。npm 分发的方式则把依赖写成node_modules依赖树,装的时候要按package.json把一堆包拉下来。

第三是落盘位置。这决定了系统能不能找到这个命令。常见的落点是/usr/local/bin、~/.local/bin、~/.npm-global/bin,Windows 上则是%APPDATA%\npm这类目录。命令本身在不在,和它在不在 PATH 里,这是两个独立的问题,后面第 5 节会专门讲这个坑。

第四是配置与缓存目录。绝大多数 CLI 工具第一次运行时会创建自己的配置目录,比如~/.config/rea或者~/.rea,里面存版本信息、缓存、凭证之类的东西。这个目录在卸载时经常被忽略,这也是“重装之后行为还是不对”的常见原因。

提示:动手之前先跑一遍type -a rea(Windows 用where rea)。如果已经有输出,说明机器上可能已经装过,先搞清楚旧版本在哪儿,再决定是覆盖还是清理,能避免八成的版本冲突问题。

1.2 两种安装方式的本质差异在哪里

把这两条路抽象一下,差异其实非常清晰:curl 脚本是一条“专用安装通道”,npm 全局安装是一条“通用包管理通道”。

curl 脚本本质上是一个安装器程序,它自己负责识别操作系统和架构、自己拼出下载地址、自己解压、自己往 PATH 里塞软链、自己打印后续操作提示。优点是对环境几乎没有前置要求,只要机器上有 curl 或者 wget 就能开工,装出来的东西也通常是一个干净的自包含目录;缺点是它是一段你不完全了解的代码,而且每个项目的安装脚本实现风格都不一样,出错时的报错信息质量参差不齐。

npm 全局安装走的是包管理器,下载、解压、依赖解析、bin 软链这些事都由 npm 统一处理,你享受到的是成熟工具链带来的可复现性和审计能力——npm ls -g --depth=0能看到装了什么版本,npm view rea versions能列出所有可装版本,卸载也是标准化的一条命令。代价是你得先有 Node.js 环境,而且很多 CLI 包的 npm 版本只是个“壳”,真正的二进制文件是在postinstall阶段另外下载的,这一步失败率不低。

1.3 三分钟选型表

先给结论,下面的表格是我自己实际选择时用的判断依据,细节解释放在后面几节。

判断维度curl 脚本安装npm 全局安装
前置依赖只需 curl 或 wget需要 Node.js 与 npm,且版本要达标
产物形态自包含目录或单文件包目录 + 依赖树 + bin 软链
默认落点脚本内定,通常是/usr/local/bin或用户目录npm 的全局 prefix 下的bin
权限要求写到系统目录时需要提权写到系统 prefix 时需要提权
版本指定靠环境变量,看脚本是否支持原生支持rea@1.4.2
升级方式重跑脚本npm i -g rea@latest
卸载干净度取决于脚本是否提供卸载入口一条命令,但缓存目录要自己清
离线安装把产物带过去即可需要离线包或私有包源
多版本共存改安装目录即可需要切 prefix 或借用版本管理器

一句话概括我的习惯:临时用、内网机器、容器镜像、没有 Node 环境的场景走 curl;本来就跑 Node 的开发机、需要锁版本复现的 CI、需要频繁切版本的场景走 npm。这个判断在后面第 4 节还会展开。

2. curl 脚本安装:一行命令背后的全部动作

2.1 安装脚本通常会做的五件事

虽然各家项目的安装脚本写法不同,但结构上高度相似,基本都跑不出这五步:检测平台与架构、拼出对应产物的下载地址、下载并校验、解压到目标目录、把可执行文件链接到 PATH 里的某个目录。有的脚本还会多一步,检查系统里是否已有旧版本并提示覆盖。

理解这五步的实际价值在于:当安装失败时,你能立刻判断是卡在哪一步。比如报错说“不支持的平台”,那是第一步的架构识别没匹配上;报错说sha256 mismatch,那是第三步的校验没过,通常是下载被截断或者拿到了一个错误页面的 HTML;装完提示成功但命令不能用,那基本是第五步的 PATH 没生效。

以检测平台这一步为例,脚本内部一般会跑类似uname -s和uname -m的组合判断。uname -m输出x86_64就对应 amd64 产物,输出aarch64或arm64就对应 arm64 产物。容器镜像里这一步特别容易翻车:在一台 arm 架构的机器上跑 amd64 的镜像,uname -m可能报出x86_64,脚本于是下载了 amd64 二进制,结果一执行就报exec format error。遇到这个报错别急着怀疑安装脚本,先确认uname -m和你以为的是不是一回事。

2.2 先下载再执行,别图省事直接管道

网上流传最多的写法是curl -fsSL <地址> | bash。这个写法确实方便,但我强烈建议你至少在第一次安装、或者在一台重要机器上安装时,改成两步走:先落到本地文件,看完再执行。

# 第一步:把安装脚本下载到本地,不执行 curl -fsSL https://install.example.com/rea/install.sh -o rea-install.sh # 第二步:审阅内容 less rea-install.sh # 第三步:确认没问题再执行 bash rea-install.sh

curl后面那几个参数值得记住:-f表示 HTTP 状态码异常时直接失败,不加这个参数的话,服务器返回一个 404 页面也会被当成脚本内容存下来,然后你执行的就是一堆 HTML;-s是静默模式,不打印进度条;-S是在静默模式下仍然输出错误信息,这两个通常一起用;-L是跟随重定向,缺了它遇到跳转就只拿到一个空文件。

审阅的时候重点看几个地方:脚本里出现的所有下载地址是不是你预期的域名;有没有sudo、rm -rf、修改 shell 配置文件的动作;写入的目录是不是你能接受的。如果你只是想在当前用户下用,不希望脚本去动/usr/local/bin,那就得看它支不支持自定义目录。

2.3 指定版本、指定安装目录的实操

大部分正经的安装脚本都会支持通过环境变量覆盖默认行为,最常见的两个是版本号和安装根目录。变量名各家不一样,一般会在脚本开头的注释或者官方文档里写明,下面用常见的命名方式举例:

# 指定版本 + 指定安装到用户目录,避免动系统目录 REA_VERSION=1.4.2 \ REA_HOME="$HOME/.local/share/rea" \ bash rea-install.sh
# 安装完成后手动确认产物落点 ls -la "$HOME/.local/share/rea" find "$HOME/.local/share/rea" -maxdepth 2 -type f -name 'rea*'

如果你不确定脚本支持哪些变量,有个笨但有效的办法:grep -n 'REA_' rea-install.sh把所有相关变量名捞出来看一眼,再结合grep -n '\${' rea-install.sh看它读了哪些环境变量。比盲猜快得多。

安装到用户目录有个额外好处:不需要 sudo,卸载时直接删目录,也不会污染系统路径。代价是你得自己确保那个目录下的bin进了 PATH,这一点在第 2.6 小节展开。

2.4 校验这一步别跳过

下载类安装最容易出问题的地方就是“下载到的不是你以为的东西”。可能是网络中断导致文件被截断,也可能是某层缓存返回了一个错误页面,还可能是在不可信的网络环境下被替换。正经的安装脚本会内置哈希校验,但如果你手动下载产物,就得自己校验。

# 计算实际哈希 sha256sum rea_1.4.2_linux_amd64.tar.gz # 与官方公布的值比对,或与随包提供的校验文件比对 sha256sum -c rea_1.4.2_checksums.txt # 如果项目提供签名,进一步验证 # 具体命令取决于签名方案,以官方文档为准

macOS 上把sha256sum换成shasum -a 256。Windows 的 PowerShell 里用Get-FileHash -Algorithm SHA256。这些命令的输出格式略有差异,但比对逻辑一样:把算出来的值和官方公布的值逐字符对一遍,别看个大概。

注意:如果安装脚本里带curl | bash这种自我执行的写法,而你又是在生产机器或者有敏感数据的机器上操作,务必先下载审阅。这不是多余的谨慎,安装脚本的权限等同于你自己敲的命令。

2.5 权限:别用 sudo 跑整个脚本

一个很常见的坏习惯是sudo bash rea-install.sh。这么做的后果是脚本创建的所有文件、目录、软链的属主都变成了 root,后续你用普通用户跑rea时,一旦它需要写缓存目录就会报权限错误,而且这个错误信息通常长得很不像权限问题,排查起来相当费劲。

更合理的做法是让脚本以普通用户身份运行,只在最后需要往系统目录写软链时用一次 sudo:

# 普通用户身份安装到用户目录 REA_HOME="$HOME/.local/share/rea" bash rea-install.sh # 只在这一步提权,把可执行文件链到系统 bin sudo ln -sf "$HOME/.local/share/rea/bin/rea" /usr/local/bin/rea # 确认软链指向正确 ls -l /usr/local/bin/rea

如果你连这一步都不想提权,那就老老实实把~/.local/bin加进 PATH,全程不需要任何特权。这个方案在多用户共享的机器上尤其合适,每个人装自己的,互不干扰。

2.6 装完了命令还是找不到:PATH 生效的正确姿势

这是 curl 方式安装后最高频的问题。脚本往~/.bashrc或者~/.zshrc里追加了一行export PATH=...,但当前这个终端窗口是读不到新配置的,因为 shell 启动时才读一次配置文件。

# 确认配置文件里确实写进去了 tail -n 5 ~/.bashrc tail -n 5 ~/.zshrc # 让当前窗口立即生效 source ~/.bashrc # 如果之前敲过一次命令,shell 可能缓存了"命令不存在",清一下缓存 hash -r # 再验证 type -a rea rea --version

hash -r这一步很多人不知道。bash 会缓存命令路径查找结果,如果你在 PATH 修好之前敲过一次rea,它会记住“这个命令不存在”,修好 PATH 后仍然报错,看起来像是没生效。type -a rea比which rea更好用,因为它会把所有同名命令都列出来,能第一时间发现机器上有几份。

2.7 内网与离线场景怎么处理

完全没有外网的机器上,curl 脚本这条路反而更省事:在有网的机器上下载好对应架构的产物压缩包和校验文件,拷到目标机器,解压到目录,加 PATH,三步就完了,全程不需要任何包管理器。

# 目标机器上 mkdir -p "$HOME/.local/share/rea" tar -xzf rea_1.4.2_linux_amd64.tar.gz -C "$HOME/.local/share/rea" --strip-components=1 # 验证可执行 "$HOME/.local/share/rea/bin/rea" --version # 加入 PATH echo 'export PATH="$HOME/.local/share/rea/bin:$PATH"' >> ~/.bashrc source ~/.bashrc

这套流程我在几台隔离环境里都用过,唯一需要注意的是--strip-components=1这个参数,取决于压缩包内部是不是带了一层顶层目录,解错了会得到一堆散落的文件。先tar -tzf看一眼结构再解,能省掉一次返工。

3. npm 全局安装:包管理器替你做的事和没做的事

3.1 npm i -g 在磁盘上到底发生了什么

一条npm i -g rea执行下去,实际发生的事情比大多数人以为的复杂,大致是这个顺序:

第一,npm 解析包名和版本范围,向配置的 registry 请求元数据,确定要装哪个具体版本,然后把 tarball 下载到本地缓存目录。

第二,把 tarball 解压到全局 prefix 下的lib/node_modules/rea目录里,同时按package.json把依赖递归装好。所以你在磁盘上看到的是一个完整的包目录,不是一个单文件。

第三,如果包的package.json里声明了bin字段,npm 会在全局 prefix 下的bin目录里创建一个指向真实入口的软链(Windows 上是一个.cmd垫片加一个.ps1垫片)。这一步才是“命令能用”的关键。

第四,执行postinstall脚本。这是最容易出问题的一环:很多 CLI 工具的 npm 包本身不含平台二进制,postinstall会根据当前平台去另外下载对应的二进制文件,放到包目录里的某个位置。这一步不走 npm 的 registry,走的是另一个下载源,因此失败原因和普通依赖安装失败完全不一样。

理解这个链条的意义在于,出问题时你能精确定位。报EACCES是第二步的权限问题;报404或ETIMEDOUT是第一步的 registry 问题;提示安装成功但命令不存在是第三步的 bin 软链没建或者 bin 目录不在 PATH 里;命令存在但一跑就报“找不到二进制”则是第四步的 postinstall 下载失败了。

3.2 标准操作序列

# 先确认 Node 与 npm 版本满足要求 node -v npm -v # 查看可安装版本,确认要装哪个 npm view rea versions --json | tail -n 20 # 装指定版本(推荐锁版本,理由见下) npm i -g rea@1.4.2 # 验证 type -a rea rea --version # 查看全局安装清单,确认版本号 npm ls -g --depth=0

关于版本锁定,这里展开一句。npm i -g rea不带版本号时,npm 会按 registry 里的latest标签装最新版。对命令行工具来说,最新版意味着不受控的行为变化——输出格式变了、参数改了、默认配置变了,都可能让你前一天还好好的脚本第二天跑挂。除非你在主动追新,否则养成带版本号的习惯,升级当成一次有意识的动作来做。

npm ls -g --depth=0这个命令值得常备。它列的是全局顶层包,输出干净,一眼能看出机器上装了哪些全局命令以及各自版本。--depth=0的意思是只看顶层,不加这个参数会连依赖树一起刷屏。

3.3 权限问题的三种解法与取舍

EACCES: permission denied是 npm 全局安装最常见的报错之一,原因是全局 prefix 指向了需要 root 权限的目录,比如某些系统上默认就是/usr/local/lib/node_modules。

三种解法,我按推荐顺序排:

第一种,改全局 prefix 到用户目录。这是我最推荐的做法,一次配置长期受益,从此所有全局包都不需要 sudo。

# 建目录 mkdir -p "$HOME/.npm-global" # 设置全局 prefix npm config set prefix "$HOME/.npm-global" # 把 bin 目录加进 PATH,写进 shell 配置 echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc source ~/.bashrc # 验证生效 npm config get prefix

第二种,用 Node 版本管理器(如 nvm、fnm、volta 这类工具)。它们本身就工作在用户目录下,全局包会装进当前 Node 版本对应的目录里,天然不需要提权。而且切 Node 版本时全局命令也跟着切,做多版本测试很方便。代价是多了一层环境复杂度,新机器上要先把版本管理器装好。

第三种,sudo npm i -g。能用,但我基本不用。它会把全局包目录的属主改成 root,导致之后不加 sudo 装包就报权限错误,形成“以后每一步都要 sudo”的恶性循环。如果已经踩进去了,用sudo chown -R $(id -u):$(id -g) <prefix目录>把属主改回来。

3.4 postinstall 下载二进制失败怎么破

前面提到过,很多 CLI 的 npm 包是“壳”,真正的二进制在postinstall阶段另外下载。这一步失败的典型表现是:npm i -g显示成功,rea --version也能跑,但一执行实际功能就报“binary not found”或者直接段错误。

排查思路是这样:

# 找到包的安装位置 npm root -g # 进去看看有没有平台二进制目录 ls -la "$(npm root -g)/rea" # 手动触发一次 postinstall,看真实报错 cd "$(npm root -g)/rea" && node ./scripts/install.js

如果确认是二进制下载失败,而该项目的 npm 包支持自定义下载源,可以设置对应的环境变量,把下载源指到内网可达的地址。变量名各项目不同,通常是REA_BINARY_HOST或者npm_config_rea_binary_host这类形式,具体要看官方文档或者package.json里scripts字段的实现。

实在搞不定的话,我的做法是:用 npm 装壳、用 curl 方式把二进制补进去,然后把 bin 软链指过去。听起来土,但在隔离环境里是有效的兜底方案。

3.5 缓存、重装与彻底清理

npm 的缓存机制有时候会让“重装”变成假重装——你以为重新下了一遍,其实拿的还是缓存里的旧 tarball。

# 校验并清理缓存 npm cache verify npm cache clean --force # 强制重装某个包 npm i -g rea@1.4.2 --force # 彻底移除 npm uninstall -g rea # 手动清掉残留的配置与缓存目录(这一步 npm 不管) rm -rf ~/.config/rea ~/.cache/rea

最后那行rm -rf需要注意:目录名是否真的是这两个,得看工具自身的实现。比较稳妥的做法是先在~/.config、~/.cache、~/.local/share下面ls | grep rea看一眼,确认之后再删。我见过有人误删了同名前缀的目录,把自己别的工具的配置清掉了。

4. 两种方式硬碰硬对比

4.1 全维度对照表

维度curl 脚本npm 全局我的评价
首次安装耗时快,通常几十秒慢,依赖多时要一两分钟差距在 CI 里会被放大
磁盘占用小,单个产物目录大,含依赖树容器镜像里影响明显
前置环境只要有 curl/wget需要 Node.js干净机器上 curl 优势大
版本可控性靠环境变量,看脚本实现原生支持精确版本npm 更规范
升级操作重跑安装脚本一条命令都很简单,但 npm 更可预期
卸载彻底性看脚本是否提供卸载标准命令,需手清缓存npm 略好
多版本共存改目录即可,天然支持要切 prefix,麻烦curl 明显占优
离线部署拷产物即可需离线包或私有源curl 明显占优
可审计性需要人工审阅脚本有 registry 元数据和完整性校验npm 更让人放心
出错信息质量参差,有时只报“失败”结构化,有错误码npm 更好排查
对系统的侵入基本只加一个软链引入全局包目录与缓存curl 更干净

4.2 三个最容易被忽略的差异

第一个是 PATH 的归属。curl 脚本装完之后,PATH 里的入口可能是脚本自己建的一个软链;npm 装完之后,PATH 里的入口是 npm 的全局 bin 目录里的软链。这两个软链指向的真实文件可能在不同位置,一旦你换了安装方式,旧软链不会自动消失,于是就出现了两份命令打架的情况。这就是我在开头说的那次“版本对不上”的根源。

第二个是卸载后的残留。npm 卸载只会删包目录和 bin 软链,运行时生成的配置目录、缓存目录、日志目录一概不动。curl 脚本一般也不提供卸载入口,删起来更没谱。所以不管用哪种方式,卸载时都要额外做一次人工清查:

# 卸载后确认有没有残留 ls -la ~/.config | grep -i rea ls -la ~/.cache | grep -i rea ls -la ~/.local/share | grep -i rea ls -l /usr/local/bin | grep -i rea ls -l ~/.npm-global/bin | grep -i rea

第三个是多版本共存。这件事上 curl 方式有天然优势:装到两个不同目录,用软链或者alias切换就行。

# 准备两个版本目录 ls -d ~/.local/share/rea-* # 用 alias 临时切换(仅当前 shell 有效) alias rea14="$HOME/.local/share/rea-1.4.2/bin/rea" alias rea15="$HOME/.local/share/rea-1.5.0/bin/rea" # 或者用软链切换默认版本 ln -sfn "$HOME/.local/share/rea-1.5.0" "$HOME/.local/share/rea-current"

npm 方式要做到同样的事,得准备两套 prefix,每次切换要改npm config set prefix,还会影响该 prefix 下的所有全局包,颗粒度太粗。所以如果你需要频繁在多个版本之间横跳做兼容性验证,我的建议是主版本用 npm 装,验证用的旧版本走 curl 方式装到独立目录,用alias调。两者互不干扰。

4.3 场景化选择建议

个人开发机,本身就在写 Node 项目:走 npm。环境已经具备,全局安装顺手,版本管理规范。

干净的 Linux 服务器,没有也不打算装 Node:走 curl。为了一个命令行工具装一整套 Node 运行时,不划算,还多了一堆需要持续打补丁的组件。

容器基础镜像:优先 curl 方式,并且务必锁死版本 + 校验哈希。npm 方式会往镜像里拉 Node 和依赖树,镜像体积能差出几十上百 MB,而且postinstall阶段需要额外网络访问,构建时容易失败。

CI 流水线:看情况。如果镜像里本来就有 Node,用 npm 加精确版本号最省事,npm ci那一套心智模型可以直接复用;如果没有,用 curl 下载固定版本的产物并校验哈希,比在流水线里现装 Node 快得多。

需要同时维护多个版本做兼容测试:curl 方式装多份到不同目录,用 alias 或软链切换。

5. 装不上、装上了跑不起来:排查实录

5.1 command not found 的排查链路

这个报错能覆盖安装问题的六成以上,按下面的顺序逐层排查,基本不会漏。

第一步,确认文件到底存不存在。

# 全局搜索一下可执行文件到底在哪 ls -l /usr/local/bin/rea ls -l ~/.local/bin/rea ls -l ~/.npm-global/bin/rea

第二步,确认它在不在 PATH 里。

echo "$PATH" | tr ':' '\n'

把输出和上一步找到的目录对一下。如果目录不在 PATH 里,那就是配置没生效,回到第 2.6 小节处理。

第三步,确认软链指向是否有效。软链指向的文件被删掉或者挪走,会出现“文件存在但不可执行”的状态,ls -l会显示一个红色的悬空链接。

readlink -f /usr/local/bin/rea ls -l "$(readlink -f /usr/local/bin/rea)"

第四步,确认 shell 缓存。hash -r之后再试。

第五步,确认执行权限。chmod +x处理一下,尤其是从压缩包手动解压出来的产物,解压工具可能没有保留可执行位。

5.2 常见问题速查表

现象最可能的原因处理方式
command not found目录不在 PATH / 软链悬空 / shell 缓存按 5.1 逐层查,hash -r
Permission denied文件无执行位,或属主是 rootchmod +x;查属主,必要时chown
EACCES安装报错npm 全局 prefix 需提权改 prefix 到用户目录
exec format error架构不匹配确认uname -m,换对应架构产物
GLIBC_2.xx not found系统运行时库版本过低用静态编译产物或换基础镜像
安装成功但功能报错postinstall二进制未下载手动触发,查下载源可达性
版本号与预期不符机器上有多份,先命中了旧的type -a rea查全部,清旧版
下载卡住或超时registry 或产物源不可达检查网络、换源、离线包
重装后行为没变配置目录残留 / npm 缓存未清清缓存,删配置目录

5.3 版本打架的定位手法

type -a rea会按 PATH 顺序列出所有同名命令,这个命令我强烈建议每个装完的人都跑一次。输出两行以上,就说明机器上有多个来源。

type -a rea # 输出示例: # rea is /home/user/.npm-global/bin/rea # rea is /usr/local/bin/rea

排序在前面的那个会被优先执行。如果你想让某个版本优先,要么调 PATH 顺序,要么把不要的那个删掉。别放任两份共存,早晚会坑到你自己——尤其是当两份版本号不一样、行为有差异的时候,报错信息看起来会完全莫名其妙。

5.4 网络受限环境的处理思路

超时和下载失败在受限环境里很常见,处理思路分三层。

第一层是延长超时和增加重试次数,对付偶发波动:

npm config set fetch-timeout 120000 npm config set fetch-retries 3

第二层是换包源地址,指向内网可达的私有源。这里不展开具体配置,各团队的基础设施不一样,思路是把registry指向一个内网能访问的地址。

第三层是离线方案。npm 有离线包的做法,可以把包和依赖打包成 tarball 带到目标机器上装;curl 方式更直接,把产物和校验文件一起拷过去就行。在严格隔离的环境里,我基本只用 curl 方式,因为它对网络的依赖只有一次下载,而且这次下载可以完全发生在另一台机器上。

6. 卸载、升级与长期维护习惯

6.1 干净的卸载流程

curl 方式的卸载,取决于安装脚本有没有提供卸载入口。有的话优先用,没有就手动来:

# 断掉软链 sudo rm -f /usr/local/bin/rea # 删掉产物目录 rm -rf "$HOME/.local/share/rea" # 清理 shell 配置里加的那行 PATH(手工编辑更安全) # 编辑 ~/.bashrc 或 ~/.zshrc,删掉 export PATH 那行

npm 方式的卸载:

npm uninstall -g rea npm cache verify # 再手工清理配置与缓存目录

两件事一定要做:一是删软链,二是清配置目录。前者决定命令还在不在,后者决定重装之后会不会继承旧状态。我遇到过重装后配置还是旧的,就是因为~/.config/rea没清。

6.2 升级策略:锁版本还是追最新

我的做法分机器:开发机可以适度追新,装个最新版试功能;CI 和内网服务器一律锁死版本,升级走一次显式的变更流程,改版本号、跑一遍冒烟测试、提交。

锁版本的具体做法:npm 方式写rea@1.4.2,或者维护一份安装清单;curl 方式把版本号写进安装命令,同时把校验哈希也写进去,这样即便上游产物被替换,安装也会失败而不是悄悄装上另一个东西。

# curl 方式锁版本的示例写法 REA_VERSION=1.4.2 bash rea-install.sh sha256sum -c rea_1.4.2_checksums.txt

6.3 我自己的落地习惯

最后分享几条我踩过坑之后固化下来的习惯,都是些小动作,但省下的时间远超过做它们的成本。

第一,装之前先type -a rea,确认现状。这一条能避免八九成的版本混乱。

第二,装完立刻跑三件事:type -a rea、rea --version、rea <某个无害的子命令>。只看版本号不够,有些情况版本号能打出来但实际功能跑不了,因为二进制没下全。

第三,安装命令一定带版本号,不进 shell 历史里留一条不带版本的裸命令,防止哪天顺手按上箭头重跑,稀里糊涂升了级。

第四,涉及提权的安装,先把脚本下载下来看一眼再执行,尤其是带curl | bash的写法。审阅脚本花三分钟,比事后排查半天划算。

第五,在一台机器上只用一种安装方式,不要两种混装。真想共存,就装到不同目录并用 alias 区分,让它们从名字上就分得开。

第六,卸载时手工清一遍配置和缓存目录。这一步没有任何工具会帮你做,但它是“重装之后行为异常”的头号原因。

这套习惯跑下来,最近一年多我在各种环境里装 rea 没再翻过车。如果你的场景比较特殊,比如完全隔离的内网、只读文件系统、或者需要在一台机器上并行跑多个版本,优先按前面几节的思路拆解,大部分问题都能归到“产物架构不对”、“PATH 没生效”、“二进制没下全”、“旧版本没清干净”这四类里,按类去查,比漫无目的地试要快得多。

返回列表