これは、なにをしたくて書いたもの?
Goで使う環境変数を知りたいなと思ったのですが、go
コマンドを見ていてenv
というコマンドがあるのに気づき。
少し見てみようかな、と。
環境
今回の環境は、こちらです。
$ go version go version go1.15.6 linux/amd64
go env
go env
コマンドの説明自体は、ドキュメントに書かれています。
Command go / Print Go environment information
デフォルトではGoの環境変数情報をシェルスクリプト(Windowsではバッチファイル形式)として、出力するコマンドです。
手元の環境では、こうなりました。
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="$HOME/.cache/go-build" GOENV="$HOME/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="$HOME/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="$HOME/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/lib/go-1.15" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/lib/go-1.15/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build915242196=/tmp/go-build -gno-record-gcc-switches"
これらの環境変数はOSの環境変数で上書きすることも可能ですが、OS上で設定されていない場合はGo内に閉じた環境変数という
扱いのようです。
なので、Goをインストールしたからといって、これらの環境変数がOSに設定されているわけではありません。
$ env | grep GO
話を戻して。
特定の環境変数のみに絞って出力することもできます。
$ go env GOOS linux $ go env GOOS GOARCH linux amd64
-json
フラグを付けると、JSON形式として出力できます。
$ go env -json { "AR": "ar", "CC": "gcc", "CGO_CFLAGS": "-g -O2", "CGO_CPPFLAGS": "", "CGO_CXXFLAGS": "-g -O2", "CGO_ENABLED": "1", "CGO_FFLAGS": "-g -O2", "CGO_LDFLAGS": "-g -O2", "CXX": "g++", "GCCGO": "gccgo", "GO111MODULE": "", "GOARCH": "amd64", "GOBIN": "", "GOCACHE": "$HOME/.cache/go-build", "GOENV": "$HOME/.config/go/env", "GOEXE": "", "GOFLAGS": "", "GOGCCFLAGS": "-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build818370082=/tmp/go-build -gno-record-gcc-switches", "GOHOSTARCH": "amd64", "GOHOSTOS": "linux", "GOINSECURE": "", "GOMOD": "", "GOMODCACHE": "$HOME/go/pkg/mod", "GONOPROXY": "", "GONOSUMDB": "", "GOOS": "linux", "GOPATH": "$HOME/go", "GOPRIVATE": "", "GOPROXY": "https://proxy.golang.org,direct", "GOROOT": "/usr/lib/go-1.15", "GOSUMDB": "sum.golang.org", "GOTMPDIR": "", "GOTOOLDIR": "/usr/lib/go-1.15/pkg/tool/linux_amd64", "PKG_CONFIG": "pkg-config" }
また、環境変数は-w NAME=VALUE
形式で設定でき、-u
で解除できるようです。これは後で試してみましょう。
Goの環境変数
ドキュメントとしては、以下に説明があります。
Command go / Environment variables
同様の内容は、以下のコマンドでも確認できます。
$ go help environment
Goの環境変数で困ったら、まずはここを見るのが良さそうですね。
環境変数を設定する
go env
では、-w
、-u
フラグで環境変数の設定ができる、ということでした。こちらを試してみます。
たとえば、$GO111MODULE
を変更してみましょう。
まずは現在の値を確認。
$ go env GO111MODULE $ go env | grep GO111MODULE GO111MODULE=""
値が入っていません。この環境変数はon
、off
、auto
の3つの値を取りうるらしいので(デフォルトはauto
)これをon
に
設定してみましょう。
設定。
$ go env -w GO111MODULE=on
確認。
$ go env GO111MODULE on $ go env | grep GO111MODULE GO111MODULE="on"
確かに変更されました。
ちなみに、この値は$GOENV
で指定されたファイルに保存されます。こんな感じですね。
$ cat `go env GOENV` GO111MODULE=on
パスは、こちらです。
$ go env GOENV $HOME/.config/go/env
では、設定した環境変数を削除してみましょう。
$ go env -u GO111MODULE
値がなくなりました。
$ go env GO111MODULE $ go env | grep GO111MODULE GO111MODULE=""
$GOENV
に指定されているファイルからも、確かに消えています。
$ cat `go env GOENV`
一時的に環境変数を変更したい場合
Goでクロスプラットフォームを意識したビルドを行う場合、$GOOS
を指定した例をよく見ます。
軽くサンプルを作ってみましょう。
$ go mod init hello-world go: creating new go.mod: module hello-world
「Hello World!!」を出力するプログラムを作成。
hello.go
package main import ( "fmt" ) func main() { fmt.Println("Hello World!!") }
これでgo build
すると、Linux用の実行ファイルが得られます。
$ go build $ ./hello-world Hello World!! $ ll hello-world -rwxrwxr-x 1 xxxxx xxxxx 2034781 1月 3 22:19 hello-world*
この時点で、手元の環境ではGoの環境変数$GOOS
の値はlinux
です。
$ go env GOOS linux
ここで、シェル上で$GOOS
をwindows
に指定して作成すると、Windows用の実行ファイルが得られます。
$ GOOS=windows go build $ ll hello-world* -rwxrwxr-x 1 xxxxx xxxxx 2034781 1月 3 22:19 hello-world* -rwxrwxr-x 1 xxxxx xxxxx 2140672 1月 3 22:20 hello-world.exe*
こんな感じですね。
で、話を戻して。go env -w
で指定してしまうと、go
コマンド全体に効いてしまうので、このように一時的に切り替えたい場合は
OSの環境変数で指定するのが良さそうですね。