Linux 執行 go 專案報錯:copy_file_range: bad file descriptor
這兩天在 Linux 環境部署一個 Go 專案遇到一個報錯:copy_file_range: bad file descriptor。網上查詢各種方法,花了兩天的時間,經過一番折騰後才解決,覺得非常有必要記錄一下過程。
一、問題復現
安裝完 Go、配置完 Go 環境以及 Beego 框架執行 Go 專案,一直報下面的錯:
期間經過 Go 解除安裝重灌、程式碼修改等一系列網上查詢的解決方法,都無濟於事,最終通過降 Go 版本成功執行專案,解決此問題。
二、解決方法
1. Linux 環境解除安裝 Go
先執行 go env
檢視 GOROOT
,我的 GOROOT=/usr/local/go
,進入 /usr/local
執行以下命令(因為我是在超級管理員下進行操作的,因此命令最前面不需要加 sudo)
rm -rf /usr/local/go
刪除軟連結:
rm /usr/bin/go /usr/bin/gofmt
2. Linux 環境安裝 Go
首先使用 wget
下載 Go 安裝包(因專案需要,我下的是 arm 架構下的 Go 版本)
附上一個 Go 安裝包下載地址:Go下載 - Go語言中文網 - Golang中文社群 (studygolang.com)
wget https://studygolang.com/dl/golang/go1.14.12.linux-arm64.tar.gz
解壓安裝包:
tar -xzf go1.14.12.linux-arm64.tar.gz -C /usr/local
建立軟連結:
ln -s /usr/local/go/bin/* /usr/bin/
檢視 Go 版本:
go version
3. 設定 Go 開發環境
在合適的位置建立工作空間和子目錄,例項如下:
mkdir -p $HOME/go/src
mkdir -p $HOME/go/pkg
mkdir -p $HOME/go/bin
因為我之前資料夾下有 pkg 和 bin 這兩個資料夾,所以就只建立了 src 資料夾,如下圖:
4. 配置環境變數
使用 vi 編輯環境變數配置檔案 $HOME/.bashrc
:
vim $HOME/.bashrc
進入編輯頁面然按 i
,移動到程式碼末尾,插入以下內容:
export GOROOT=/usr/local/go #設定為go安裝的路徑,有些安裝包會自動設定預設的goroot
export GOPATH=$HOME/go #預設的Golang專案的工作空間
export GOBIN=$GOPATH/bin # go install命令生成的可執行檔案的路徑
export PATH=$PATH:$GOROOT/bin:$GOBIN
之後按 Esc
鍵,輸入 :wq
儲存退出。
使配置檔案生效:
source $HOME/.bashrc
可執行 go env
檢視 Go 環境變數:
go env
下圖是我配置完的 Go 環境變數,主要注意著畫紅線的這三個配置:
5. 安裝 Beego
執行命令:
go get github.com/astaxie/beego
安裝 bee 工具執行命令:
go get github.com/beego/bee
通常都會安裝成功,但也不排除特殊情況,比如我。此時試一下這行命令:
go get -u github.com/beego/bee
神奇地發現安裝成功了。
這裡可能也會遇到 timeout 的問題,可以參考一下我的這篇文章:goproxy 模組代理,解決 timeout 問題。
進入專案目錄,然後執行:
bee run
發現專案成功執行:
三、原因
授人以魚不如授人以漁,找到成功解決的方法當然是建立在找到問題原因的基礎上。
經過我的一番查閱資料,發現是因為我之前安裝的 Go 是 1.15.5 版本,而這篇文章 Go 1.15中值得關注的幾個變化 | Tony Bai 提到:
我的理解就是:Go 1.11 - Go 1.14 的版本執行 Go 專案應該是需要這個 go.mod 檔案。
而 Go 1.15 版本則是通過環境變數裡的這個來實現的:
因為專案是在 Go 1.15 之前的版本下開發的,因此 /pkg/mod 下可能沒有需要的檔案,因此導致專案執行不起來,不知道我的理解對不對,獻醜了。
可以看到下圖 Go 1.14 中的環境變數,是沒有 GOMODCACHE
這一條的。
四、致謝
golang bad file descriptor_benben的部落格-CSDN部落格:此文章的方法不適用於我這個問題,但是也要感謝作者寫的此篇文章。
linux下go安裝/解除安裝重灌:此文章的解除安裝 Go 方法有用到。
Linux下Go的安裝、配置 、升級和解除安裝:此文章的安裝與解除安裝 Go 方法有用到。
linux安裝golang 以及beego框架:此文章的安裝 beego 與 bee 工具方法有用到。
Go 1.15中值得關注的幾個變化 | Tony Bai:此文章找到了問題所在:是 Go 版本不同導致的。