1. 程式人生 > 實用技巧 >Linux 執行 go 專案報錯:copy_file_range: bad file descriptor

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

,刪除 go 資料夾。

執行以下命令(因為我是在超級管理員下進行操作的,因此命令最前面不需要加 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 版本不同導致的。