在一臺機器上安裝並使用多版本的 Go ?

1. 需求背景

實際開發中會接觸到不同的開源項目,而這些項目有可能是不同團隊開發的,使用的 go 版本都是不一樣的。

以我爲例,最近在研究 KubeVirt (一個能在 K8S 下管理虛擬機的開源項目),爲了實現自己的需求,需要對 KubeVirt 進行二次開發。

通過 go.mod 得知 KubeVirt 是使用 go 1.13 開發的,而同時爲了能在 KubeVirt 下的虛擬機能使用 LVM 這種存儲方式,我們又引入了阿里研發的 lvm-csi 插件,同樣的,這個插件已經實現的功能距離我們的預期還有點差距,因此同樣要進行二次開發。查看 go.mod 發現,lvm-csi 是在更老的版本下開發的,也就是 go 1.12 。

而同時我的機器上很早之前就安裝過 go 1.14 的版本,也一直使用它來開發。

問題就來了,如何讓才能在我的機器上能同時安裝這麼多個版本的 golang ,而且互不衝突呢?

2. 安裝多版本的 Go

要想不同版本的 go 互不衝突,只要將他們安裝在不同的目錄下就可以了。

首先下載兩個版本的安裝包

$ wget https://dl.google.com/go/go1.12.linux-amd64.tar.gz
$ wget https://dl.google.com/go/go1.13.linux-amd64.tar.gz

然後分別解壓至不同目錄

# 解壓go 1.12
sudo tar -C /tmp/ -xzf go1.12.linux-amd64.tar.gz
mv /tmp/go /usr/local/go12 

# 解壓go 1.13
sudo tar -C /tmp/  -xzf go1.13.linux-amd64.tar.gz
mv /tmp/go /usr/local/go13

3. 簡單粗暴的方案

在同一臺機器中安裝多個版本的 Golang 需要注意

  • 區分不同版本的 go 入口

  • 切換使用不同的環境變量

區分不同版本 go 入口

當你在環境中有多個 go ,那麼當你使用 go build 等命令時,系統如何知道你想要使用的是哪個版本呢?

系統並不知道,因此你需要爲不同版本的 go 起不同的名字

  • go 1.12 的 go 入口就改成 /usr/local/go12/bin/go12
  • go 1.13 的 go 入口就改成 /usr/local/go13/bin/go13
  • 以此列推

如此一來,就不會混淆了

$ go12 version
go version go1.12 linux/amd64
$ go13 version
go version go1.13 linux/amd64

切換使用不同的環境變量

使用了不同的go入口,對應的環境變量也要變量,比如 GOROOT,它可不會隨着你使用哪個版本的 go 就自動切換,看下面他們輸出的都是一個值。

$ go12 env GOROOT
/usr/local/go
$ go13 env GOROOT
/usr/local/go

因此,這個切換不同環境變量得自己來做

另外要注意的是

  1. go 1.12 沒有 go env -w 中的 -w 參數
  2. go 1.13 中雖然有 -w 但不能覆蓋OS級別的環境變量,修改前需先 unset

知道了這幾點之後,便可以自行實現切換的方案。

我想的方案是可以在 /usr/local/go13/bin/ 寫一個修改環境變量的腳本

$ cat << EOF >/usr/local/go12/bin/goto12
unset GOROOT
go env -w GOROOT="/usr/local/go12/"
EOF

$ chmod +x /usr/local/go12/bin/goto12

下次要使用 go 1.12 的時候,直接使用下面命令就可以修改環境變量

$ source goto12

go 1.13 也是同理,不敢贅述。

實現的效果如下

$ go env GOROOT
/usr/local/go

$ source goto12
$ go12 env GOROOT
/usr/local/go12

$source goto13
$ go13 env GOROOT
/usr/local/go13

4. 比上面更優的方案

到這裏,你應該已經感受到了,每次切換都要手動 source 一下,還是有點麻煩。

其實我還有一個更好的方法,這種方案,可以不用去改 go 入口的名字,同樣連 source 都不用。

只要執行下面兩條件命令即可(每個版本兩條,兩個版本就是四條)

$ cat << EOF >/usr/local/go12/bin/go12
unset GOROOT
go env -w GOROOT="/usr/local/go12/"
/usr/local/go12/bin/go $@
EOF

$ chmod + /usr/local/go12/bin/go12

$ cat << EOF >/usr/local/go13/bin/go13
unset GOROOT
go env -w GOROOT="/usr/local/go13/"
/usr/local/go13/bin/go $@
EOF

$ chmod + /usr/local/go13/bin/go13

如果一來,當你執行 go12 就會自動修改 go12 的環境變量,執行 go13 就會自動修改 go13 的環境變量,並且不會影響默認的 go 的行爲。

當然以上我都只改了 GOROOT 這一環境變量,若在不同的 go 版本還有其他不一樣的地方,可以繼續在 go12 或者go13 中添加對應的 shell 代碼。

絮叨一下

我在 『開源中國』寫過很多的 Python 相關文章,其中包括 Python 實用工具,Python 高效技巧,PyCharm 使用技巧,很高興得到了很多知乎朋友的認可和支持。

在他們的鼓勵之下,我將過往文章分門別類整理成三本 PDF 電子書

PyCharm 中文指南

《PyCharm 中文指南》使用 300 多張 GIF 動態圖的形式,詳細講解了最貼合實際開發的 105個 PyCharm 高效使用技巧,內容通俗易懂,適合所有 Python 開發者。

在線體驗地址:https://pycharm.iswbm.com

Python 黑魔法指南

《Python黑魔法指南》目前迎來了 v3.0 的版本,囊集了 100 多個開發小技巧,非常適合在閒時進行碎片閱讀。

在線體驗地址:https://magic.iswbm.com

Python 中文指南

學 Python 最好的學習資料永遠是 Python 官方文檔,可惜現在的官方文檔大都是英文,雖然有中文的翻譯版了,但是進度實在堪憂。爲了照顧英文不好的同學,我自己寫了一份 面向零基礎的朋友 的在線 Python 文檔 -- 《Python中文指南》

在線體驗地址:https://python.iswbm.com

有幫助的話,記得幫我 @王炳明 點個贊喲~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章