跳转至

新机器配开发环境:zsh、uv、Node.js

新 Ubuntu 机器从零配到能写代码:按顺序装 zsh、uv、Node.js,每一步都是复制粘贴到终端里跑。最容易错的是第 3 步:装完 zsh 不改 $SHELL 就装 nvm,nvm 会把自己写进 ~/.bashrc,打开 zsh 就找不到 nvm 和 node。

下载基本都走 GitHub,uv 的安装包也放在 GitHub Releases 上。机器访问不了 GitHub 就先做第 0 步,借外网服务器开 SSH 代理;这里没写镜像方案。

0. 访问不了 GitHub 就先开 SSH 代理

能直连 GitHub 就跳过,展开看命令

用 SSH 连一台外网服务器,在本机 1080 端口开一个 SOCKS5 代理,再让当前 shell 的下载都走它:

# -D 在本机 1080 端口开 SOCKS5 代理,-N 不开远程 shell,-f 登录完转后台
ssh -fN -D 1080 ubuntu@age:YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRTEVLYmxwc0pLSXFVNFlpOVdkandrY3hYOGlsck1VMzVKbnpHVDBwM1FRCktKWFg1MDlGb3pudjRzMjNTWnVvWVBxaWdJeDd2UFZmZEtWN2RsYWpBMVEKLS0tIFluNVo3dmhDMWxadW0wSlEyblZEQkhyNVYybWJvWTZzVTlQa1pUTUV4NWcKOxFlU2JmfvCeqFHSUE2BMsrnO/mct5r3MbNWiC1oJIFXLFDn3/a/SDx29OE=

export ALL_PROXY=socks5h://127.0.0.1:1080
export HTTP_PROXY=socks5h://127.0.0.1:1080
export HTTPS_PROXY=socks5h://127.0.0.1:1080

ssh 问密码时填 age:YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlbVdTNGk1MFNZWWIzZWdhckcvT21kRDM3ZVVVVjJxU1gzdGtaSnB6MlNNCnMyb1BTaE5EODdmK2xYYmd5UURLK2xDNE5GZExpSGFQZmtqVzBSV2pEclUKLS0tIGFrcXFrdjRqKzVaUGpBcXNqUHNYY21ZOHJaWUVMYk84UTNrMXJ0UkpkSU0KWPtwciteS4n+zH7vUW5e5Mkvf39C+JXmBGhbCaBbGXv5I2aEdp8hqNR+Q7h7fu68WA==。服务器地址和密码都打了码,点马赛克解锁,规矩见写作规范的打码一节。

验收:curl -sI https://github.com | head -1 打印 HTTP/2 200。

  • socks5h 的 h 表示域名也交给服务器解析——本机 DNS 查到的 GitHub 地址可能本身就不通。
  • 变量只在当前 shell 里有效:第 3 步的 exec zsh 会原样继承,断开 SSH 重新登录就要再 export 一遍。
  • sudo 默认清掉环境变量,第 1 步的 apt-get 照旧直连。
  • 后面的下载全靠 curl 和 git,两者都认 socks5h://;wget 不支持 SOCKS,好在 uv 和 nvm 的安装脚本有 curl 时都优先用 curl。

1. 装 zsh

sudo apt-get update && sudo apt-get install -y zsh git curl wget

2. 装 Oh My Zsh 和插件

只在新机器上跑

第一行会删掉 ~/.oh-my-zsh 重装,里面自己加的主题和插件会丢。旧的 ~/.zshrc 不用管,安装器会自己把它备份成 ~/.zshrc.pre-oh-my-zsh。

# ~/.oh-my-zsh 已存在时安装器会直接退出,所以先删
rm -rf ~/.oh-my-zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended

# 自动补全、语法高亮两个插件
ZSH_CUSTOM=${ZSH_CUSTOM:-~/.oh-my-zsh/custom}
git clone https://github.com/zsh-users/zsh-autosuggestions $ZSH_CUSTOM/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git $ZSH_CUSTOM/plugins/zsh-syntax-highlighting
sed -i 's/plugins=(git)/plugins=(git zsh-autosuggestions zsh-syntax-highlighting)/' ~/.zshrc

3. 设成默认 shell,改 $SHELL 再进 zsh

sudo chsh -s "$(command -v zsh)" "$USER"
export SHELL="$(command -v zsh)" && exec zsh

验收:echo $SHELL 的结果以 zsh 结尾。

第二行不能省。$SHELL 是登录那一刻从 /etc/passwd 抄进环境变量的,之后没有任何东西会更新它:

  • chsh 只改 /etc/passwd,当前会话不受影响。
  • 单独跑 exec zsh 只是换了进程,环境变量原样继承,echo $SHELL 仍然是 /bin/bash。

所以要先 export 再 exec。断开 SSH 重新登录也行,登录时会重新读 /etc/passwd。

这一步只影响按 $SHELL 挑 rc 文件的安装器。2026-09-30 读了下面两个安装脚本:

安装器 往哪写 PATH $SHELL 还是 bash 时
uv 0.12.21 不看 $SHELL:.profile、.bashrc 这类 bash 文件存在的都写,.zshrc/.zshenv 写第一个存在的 没影响
nvm v0.40.3 nvm_detect_profile1 先认 $PROFILE,再看 $SHELL 里含 bash 还是 zsh 只写 ~/.bashrc

4. 装 uv

curl -LsSf https://astral.sh/uv/install.sh | sh
# 代替重启 shell
source $HOME/.local/bin/env

验收:uv --version 能打印版本号。

5. 装 Node.js

nodejs.org 下载页给的命令,原样照抄:

# 下载并安装 nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# 代替重启 shell
\. "$HOME/.nvm/nvm.sh"
# 下载并安装 Node.js:
nvm install 26
# 验证 Node.js 版本:
node -v    # v26.x.x
# 验证 npm 版本:
npm -v     # 11.x.x

验收:

grep -c NVM_DIR ~/.zshrc     # 非 0
grep -c NVM_DIR ~/.bashrc    # 0;不是 0 说明第 3 步漏了

漏了第 3 步,就指定 PROFILE 重跑一遍安装命令。nvm 看到 .zshrc 里还没有自己,就会补写进去:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | PROFILE="$HOME/.zshrc" bash

6. 装 Caddy(要做反向代理的机器才装)

版本必须 ≥ 2.11,装完用 caddy version 确认——Ubuntu 自带源里的只有 2.6.2。用 apt 装,不用 docker:Caddy 要占宿主机的 80/443,放进容器也得用 host 网络。

没做的

  • 只写了 Ubuntu(apt),其他发行版和 macOS 没写。

  1. nvm_detect_profile,2026-10-01 读。 ↩