“环境变量”这个词,有经验的开发同学对它一定很熟悉了,它提供给软件工程以高灵活性、高扩展性,大到操作系统,小到某个项目,都有它的影子,它的表现方式有很多。

.env 

很多大型项目会使用环境变量进行配置,作为配置选项的环境变量大大简化了应用程序的部署。这些在云基础设施中也很常见,一个大型项目中通常会配备一个提供环境变量配置服务的配置平台,包括 AB 平台也可以看作是此类的一个例子。

百度百科上的定义,环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。

那么在 Go 中,环境变量通常是什么表现形式呢?有两种很常见,分别是 Go 开发必需的环境变量、普通环境变量

Go 开发必需的环境变量

开发 Go,必须在安装 Go 语言开发工具后,再配置 Go 语言自带的开发所必需的环境变量,才算搭建好了基本的 Go 开发环境,进行接下来的 Go 项目管理和开发。

可以使用以下命令查看系统中的Golang环境变量,

// 打印 Go 所有默认的环境变量
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/shouyuan/Library/Caches/go-build"
GOENV="/Users/shouyuan/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/shouyuan/workspace/project/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/shouyuan/workspace/project/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn,direct"
GOROOT="/opt/homebrew/Cellar/go@1.16/1.16.15/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/homebrew/Cellar/go@1.16/1.16.15/libexec/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.16.15"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/yy/5wksklpj00j341q9w0r3jhxh0000gn/T/go-build2304754593=/tmp/go-build -gno-record-gcc-switches -fno-common"

// 打印某个环境变量的值
$ go env GOPATH
/Users/shouyuan/workspace/project/go
$ go env GOPATH GOROOT
/Users/shouyuan/workspace/project/go
/opt/homebrew/Cellar/go@1.16/1.16.15/libexec

环境变量的设置,会影响我们开发和编译项目的过程与结果,所以还是很有必要了解一下的。虽然常常需要我们配置的环境变量就那么几个,但 Go 语言提供了很多默认的环境变量,让我们可以自由地定制开发和编译器行为。上面这些环境变量中,有些伴随着 Go 一起出现在人们面前,比如 GOPATH;而有些则是随着 Go 语言的发展逐步出现,甚至不同 Go 版本同一名字的环境变量意义也会有不同,比如 GO111MODULE;有些环境变量我们可以永远都不会用到,大概了解一下就可以了。

通用的

GCCGO
GOARCH
GOBIN
GOCACHE
GOFLAGS
GOOS
GOPATH
GOPROXY
GOPRIVATE
GO111MODULE
GORACE
GOROOT
GOTMPDIR

和 cgo 一起使用的

CC
CGO_ENABLED
CGO_CFLAGS
CGO_CFLAGS_ALLOW
CGO_CFLAGS_DISALLOW
CGO_CPPFLAGS, CGO_CPPFLAGS_ALLOW, CGO_CPPFLAGS_DISALLOW
CGO_CXXFLAGS, CGO_CXXFLAGS_ALLOW, CGO_CXXFLAGS_DISALLOW
CGO_FFLAGS, CGO_FFLAGS_ALLOW, CGO_FFLAGS_DISALLOW
CGO_LDFLAGS, CGO_LDFLAGS_ALLOW, CGO_LDFLAGS_DISALLOW
CXX
PKG_CONFIG
AR

和系统架构体系相关的

GOARM
GO386
GOMIPS
GOMIPS64

专用的

GCCGOTOOLDIR
GOROOT_FINAL
GO_EXTLINK_ENABLED
GIT_ALLOW_PROTOCOL

其他

GOEXE
GOHOSTARCH
GOHOSTOS
GOMOD
GOTOOLDIR

注意:Go 提供的 Windows 安装包(.msi 后缀)安装完成后,会自动配置几个常用的环境变量。

记录几个常见的(GOROOT、GOPATH、GOBIN、GOOS、GOARCH、GOPROXY、GOPRIVATE、GO111MODULE)

GOROOT

GOROOT 
Windows GOROOT C:/goMac Linux GOROOT usr/loca/go
GOROOT/bin GOROOT/bin 
// Mac 上通过 brew install go 安装之后,找到对应的安装目录设置即可
export GOROOT=/opt/homebrew/Cellar/go/1.18/libexec
export PATH=$PATH:$GOROOT/bin

GOPATH

GOPATH GOPATH GOROOT 
类 Unix GOPATH 

我们可以通过修改GOPATH来更换工作区,

export GOPATH=$HOME/workspace/project/go
go get 
export GOPATH=$HOME/workspace/project/go;$HOME/go
src、pkg、bin,后来 go module 包管理方法(计划写一篇文章专门来总结)出现后,弱化了这种组织规则。其中,src 包,pkg bin 存放

GOBIN

GOBIN 
go install GOPATH/bin 
export GOBIN=$GOPATH/bin

GOOS 和 GOARCH

学习这两个环境变量的用法,就得了解什么是交叉编译_满守园的博客-CSDN博客。

在其他编程语言中进行交叉编译可能要借助第三方工具,但在 Go 语言进行交叉编译非常简单,最简单只需要设置 GOOS 和 GOARCH 这两个环境变量就可以了。

GOOS 的默认值是我们当前的操作系统,比如 Windows、Linux,注意 Mac 操作的上的值是darwin。 GOARCH 则表示 CPU 架构,如 386、amd64、arm等。

GOOS 和 GOARCH 的值成对出现,而且只能是下面列表对应的值。

$GOOS	    $GOARCH
android	    arm
darwin	    386
darwin	    amd64
darwin	    arm
darwin	    arm64
dragonfly   amd64
freebsd	    386
freebsd	    amd64
freebsd	    arm
linux	    386
linux	    amd64
linux	    arm
linux	    arm64
linux	    ppc64
linux	    ppc64le
linux	    mips
linux	    mipsle
linux	    mips64
linux	    mips64le
linux	    s390x
netbsd	    386
netbsd	    amd64
netbsd	    arm
openbsd	    386
openbsd	    amd64
openbsd	    arm
plan9	    386
plan9	    amd64
solaris	    amd64
windows	    386
windows	    amd64

编译在 64 位 Linux 系统上运行的程序,

$ GOOS=linux GOARCH=amd64 go build main.go

编译 arm 架构 Android系统上运行的程序,

$ GOOS=android GOARCH=arm GOARM=7 go build main.go

GOPROXY

从 Go 1.11 版本开始,官方支持了 go module 包依赖管理工具。不仅如此, Go 1.11 还新增了 GOPROXY 环境变量。如果设置了该变量,下载源代码时将会通过这个环境变量设置的代理地址。Go modules 的扶正是在 Go 1.13 发布中开发者能直接感觉到的最大变化,GOPROXY 环境变量在 Go 1.13 中的用法也发生了一些变化,具体参见https://golang.org/doc/go1.13

goproxy.io 提供了一个开源的解决方案允许开发者一键构建自己的 GOPROXY 代理服务,同时也提供了公用的代理服务 https://goproxy.io,参见Goproxy.io Enterprise 企业版本功能介绍;七牛云也出了个国内代理 goproxy.cn 方便国内用户更快的访问,参见Goproxy.cn、goproxy.cn - 为中国 Go 语言开发者量身打造的模块代理。

没有用 GOPROXY 环境变量的表现,

使用 GOPROXY 变量后,可以正常拉取程序包,golang 的 goproxy 配置方法参见golang的goproxy配置 - Go语言中文网 - Golang中文社区。

GOPRIVATE

go get 通过代理服务拉取私有仓库(企业内部 module 或托管站点上的 private 库),而代理服务不可能访问到私有仓库,会出现了 404 错误。Go1.13 版本提供了一个方便的解决方案:GOPRIVATE 环境变量。

eg.

export GOPRIVATE=*.corp.example.com,rsc.io/private

参见 GOPRIVATE 环境变量、GOLANG 环境几个重要的env配置参数解析、一文说清GO环境变量

GO111MODULE

Golang 官方建议是一个项目一个 GOPATH,但是由于麻烦,很多人都不这么做,在 Go 1.11 中推出了 go modules 来解决依赖管理的问题,GO111MODULE 正是控制 go modules 的开关,在 Go 1.13 中也进行了功能升级, 具体参见https://golang.org/doc/go1.13、go语言:环境变量GOPROXY和GO111MODULE设置。

普通环境变量

环境变量是系统级的键-值对,正在运行的进程可以访问它。这些通常用于使同一程序在不同的部署环境(例如 PROD、DEV 或 TEST)中表现不同。在环境中存储配置是 twelve-factor 应用程序的原理之一,它使应用程序具有可移植性。如何在 Go 程序代码中设置、获取以及列出环境变量,也是非常重要的一环。

目前 Go 中有下面几种在代码里边访问环境变量的方式,

os

2. 使用第三方包(GoDotEnv、Viper)

ViperGoDotEnvvipergodotenv。ViperGithubGoDotEnvgonfiggo-akka

Have Fun