これは、なにをしたくて書いたもの?
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の環境変数で指定するのが良さそうですね。