在 Ubuntu 上管理 Go 版本,难点通常不在“怎么装”,而在“怎么切得稳”。一台机器上既要兼顾老项目的固定版本,又想试用新版本特性,选对管理方式比单纯装多个二进制包更重要。下面按使用场景拆开讲清楚 4 种常见方案,并补上切换逻辑、适用边界和验证方法,方便你判断该用系统工具、版本管理器,还是直接手动维护。
为什么需要在 Ubuntu 上管理多个 Go 版本
这类需求在开发环境里很常见,尤其是以下几种情况:
- 同时维护多个项目,而它们依赖的 Go 版本并不一致;
- 想测试新版本,但又不希望影响当前稳定环境;
- 需要在系统级、用户级或项目级之间选择合适的切换粒度。
如果你只是偶尔切一次版本,系统自带方式已经够用;如果经常在项目间来回切换,专用版本管理器会更省事。
方案一:用 update-alternatives 做系统级切换
update-alternatives 是 Ubuntu 自带的软链接管理工具,适合把多个 Go 可执行文件注册到系统里,再切换默认版本。它的特点是简单直接,尤其适合单机开发环境或需要统一系统默认版本的场景。
安装并注册多个 Go 版本
先下载需要的二进制包,例如 go1.20.3.linux-amd64.tar.gz 和 go1.21.0.linux-amd64.tar.gz,再解压到 /usr/local:
sudo tar -C /usr/local -xzf go1.20.3.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz
随后把不同版本注册到 update-alternatives:
sudo update-alternatives --install /usr/bin/go go /usr/local/go1.20.3/bin/go 1
sudo update-alternatives --install /usr/bin/go go /usr/local/go1.21.0/bin/go 2
这里最后的数字是优先级,数值越大,默认优先级越高。
如何切换与验证
注册完成后,执行下面的命令切换:
sudo update-alternatives --config go
系统会列出所有已注册版本,输入对应编号即可切换。切换后用下面的命令确认当前版本:
go version
如果你的目标是“让整台机器默认使用某个 Go 版本”,这一套方式通常最省心。
方案二:用 gvm 管理 Go 多版本
gvm(Go Version Manager)是专门为 Go 准备的版本管理工具。相比系统级软链接方式,它更偏向用户态管理,安装、切换、设置默认版本都集中在同一套命令里。
安装 gvm
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
source ~/.gvm/scripts/gvm
安装完成后,记得加载环境变量。然后安装指定 Go 版本:
gvm install go1.20.3
gvm install go1.21.0
切换临时版本和默认版本
gvm 的优势在于切换命令很直观:
gvm use go1.20.3 # 临时切换
gvm use go1.21.0 --default # 设为默认版本
切换后同样可以通过下面的命令确认:
go version
如果你的主要诉求是“只管 Go,而且希望安装和切换都尽量统一”,gvm 会比系统工具更顺手。
方案三:用 asdf 统一管理 Go 和其他语言
如果你不只维护 Go,还同时维护 Python、Node.js、Ruby 等语言环境,那么 asdf 的价值会更明显。它通过插件机制管理不同语言版本,更适合多语言开发者把版本管理入口统一起来。

安装 asdf 与 Go 插件
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.8.1
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
echo '. "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
source ~/.bashrc
然后添加 Go 插件:
asdf plugin-add golang https://github.com/asdf-community/asdf-golang.git
安装需要的 Go 版本:
asdf install golang 1.20.3
asdf install golang 1.21.0
全局版本与项目版本怎么切
asdf 支持全局版本和目录级版本两种模式:
asdf global golang 1.21.0 # 全局默认版本
asdf local golang 1.20.3 # 当前目录版本(会生成.golang-version文件)
这意味着你可以让系统默认使用 1.21.0,但某个旧项目进入目录后自动使用 1.20.3。最后用下面的命令验证:
go version
如果你重视“按项目隔离版本”,而且机器上语言种类较多,asdf 往往是更长期的选择。
方案四:手动安装并通过环境变量切换
手动管理的优点是路径、目录结构和切换方式都完全由你控制,适合对环境有明确要求,或者不想额外引入管理工具的场景。代价是维护成本更高,切换时也更容易出错。
下载、解压并整理目录
从 Go 官网下载对应版本的二进制包,例如 go1.20.3.linux-amd64.tar.gz,然后解压到不同目录,例如 /usr/local/go1.20 和 /usr/local/go1.21:
sudo tar -C /usr/local -xzf go1.20.3.linux-amd64.tar.gz
解压后目录名可能默认就是 go,建议重命名成带版本号的形式,便于后续区分和维护。
通过 GOROOT 和 PATH 切换版本
编辑 ~/.bashrc 或 ~/.zshrc,修改环境变量:
export GOROOT=/usr/local/go1.21.0
export PATH=$GOROOT/bin:$PATH
保存后执行:
source ~/.bashrc
然后再检查当前生效版本:
go version
这种方式最灵活,但也最依赖你自己维护环境变量的一致性。
怎么选方案,以及还有哪些注意事项
如果只看使用场景,通常可以这样判断:
- 希望系统默认版本可切换,优先考虑
update-alternatives; - 只管理 Go,想要更专用的体验,可以选
gvm; - 同时管理多种语言,
asdf更适合长期使用; - 需要完全自定义路径和环境,手动管理最灵活。
源码编译场景下的依赖
如果你不是直接使用官方二进制包,而是打算从源码手动编译安装 Go,需要先准备一些基础依赖:
sudo apt install -y build-essential git
尽量配合 Go Modules 使用
无论采用哪种版本管理方式,都建议在项目里使用 Go Modules 管理依赖,例如执行 go mod init。这样可以尽量减少不同 Go 版本切换时的依赖兼容问题,也更符合当前 Go 项目的主流实践。













