🔖

【Go】.envを使って環境変数を読み込む(godotenv) +osパッケージでenvを触ってみる。

2021/06/27に公開
1

はじめに

Goの「godotenv」パッケージを使って環境変数を読み込んでみます。
普通に使うパターンと、「os」パッケージで色々やってみようと思います。

環境

go 1.16

早速やってみる

まずは設定から

// go mod を入れます。今回はexample.comにしてます。
$ go mod init example.com
// godotenv をインストールします。
$ go get github.com/joho/godotenv
// go mod を更新します。
$ go mod tidy

これで設定完了。
次は.envに環境変数を置いてみます。

.env

.env
SAMPLE_MESSAGE=これはサンプルです。

一旦これだけです。

次はmain.goにコードを書いていきます。

main.go

main.go
package main

import (
	"fmt"
	"os"

	"github.com/joho/godotenv"
)

func main() {
	//func loadEnvを呼び出します。
	loadEnv()
}

// .envを呼び出します。
func loadEnv() {
	// ここで.envファイル全体を読み込みます。
	// この読み込み処理がないと、個々の環境変数が取得出来ません。
	// 読み込めなかったら err にエラーが入ります。
	err := godotenv.Load(".env")
	
	// もし err がnilではないなら、"読み込み出来ませんでした"が出力されます。
	if err != nil {
		fmt.Printf("読み込み出来ませんでした: %v", err)
	} 
	
	// .envの SAMPLE_MESSAGEを取得して、messageに代入します。
	message := os.Getenv("SAMPLE_MESSAGE")

	fmt.Println(message)
}

go run main.goします。

出力結果

これはサンプルです。

となります。
上手くいきました。

.envに設定した、「SAMPLE_MESSAGE」という環境変数を
os.Getenvで取得してmessageという変数に代入し、それをfmt.Printlnで出力しました。

次はosパッケージで色々試してみます。

色々やってみる。

os パッケージの中のenvと名がつくものを試してみます。

Setenv(key, value string) error

Setenvは、キーで指定された環境変数の値を設定します。エラーがある場合は、エラーを返します。
.envファイルに直書きするのではなく、ここでenv環境変数の設定をするという事。

// "SETENV_MESSAGE"という環境変数に"メッセージをセットします。"という文字列を設定します。
os.Setenv("SETENV_MESSAGE", "メッセージをセットします。")
// "SETENV_MESSAGE"を取得して、messageという変数に代入します。
message := os.Getenv("SETENV_MESSAGE")

fmt.Println(message)

出力

メッセージをセットします。

Setenvを使えば.envファイルは使わないで済みます。

Unsetenv(key string) error

Unsetenvは、単一の環境変数の設定を解除します。
Setenvで設定した環境変数を解除するということ。

// "SETENV_MESSAGE"という環境変数に"メッセージをセットします。"という文字列を設定します。
os.Setenv("SETENV_MESSAGE", "メッセージをセットします。")
// UnsetenvでSetenvで設定した"SETENV_MESSAGE"を解除します。
os.Unsetenv("SETENV_MESSAGE")
// "SETENV_MESSAGE"を取得して、messageという変数に代入します。(Unsetenvで解除されているため、代入出来ない)
message := os.Getenv("SETENV_MESSAGE")

fmt.Println(message)

出力


解除されている為、何も出力されません。
使い方としては

defer os.Unsetenv("SETENV_MESSAGE")

deferと一緒に使い、最後に実行するようです。

Clearenv()

Clearenvは、すべての環境変数を削除します。

// 3つの環境変数に3つの文字列を設定します。
os.Setenv("SETENV_MESSAGE", "メッセージをセットします。")
os.Setenv("NAME", "エーイチ")
os.Setenv("HEIGHT", "170")

// 全ての環境変数を解除します。
os.Clearenv()

// 環境変数より値を取得して変数に代入します。(解除されている為、代入出来ません)
message := os.Getenv("SETENV_MESSAGE")
name := os.Getenv("NAME")
height := os.Getenv("HEIGHT")

fmt.Println(message)
fmt.Println(name)
fmt.Println(height)

出力


Clearenvされている為、何も出力されません。
Setenvで設定されている環境変数が全て解除されます。
.envファイルにある環境変数も解除されます。
ポイントは、Getenvの前にあるか、後にあるかです。

main.go
godotenv.Load(".env")

os.Setenv("SETENV_MESSAGE", "メッセージをセットします。")
os.Setenv("NAME", "エーイチ")
os.Setenv("HEIGHT", "170")
	
message := os.Getenv("SETENV_MESSAGE")
os.Clearenv()
name := os.Getenv("NAME")
height := os.Getenv("HEIGHT")
sample := os.Getenv("SAMPLE_MESSAGE")

fmt.Println(message)
fmt.Println(name)
fmt.Println(height)
fmt.Println(sample)
.env
SAMPLE_MESSAGE="これはサンプルです。"

出力

メッセージをセットします。

message := os.Getenv("SETENV_MESSAGE")
だけがos.Clearenvの前にあったので、これだけ出力されました。

Getenv(key string) string

さっき使いましたね。
環境変数を取ってきます。
Setenv した環境変数と、.envで設定されている環境変数を取得する事が出来ます。
.envで設定されている環境変数を取得する為には、

godotenv.Load(".env")

の記載が必要です。

LookupEnv(key string) (string, bool)

Getenvと同じような使い方です。
違いは value と bool が返るところです。
変数が環境に存在する場合、値(空の場合があります)が返され、ブール値はtrueになります。それ以外の場合、戻り値は空になり、ブール値はfalseになります。

func main() {

	os.Setenv("SETENV_MESSAGE", "メッセージをセットします。")
	os.Setenv("EMPTY_MESSAGE", "")

	show("SETENV_MESSAGE")
	show("EMPTY_MESSAGE")
	show("MISSING_MESSAGE")
}

func show(key string) {
	// key として渡された環境変数の値を取得して、変数valに代入します。
	// 代入が成功すればokにtrueが入り、失敗すればfalseが返ります。
	val, ok := os.LookupEnv(key)
	// 代入が失敗ならkey はセットされていません。が出力されます。
	if !ok {
		fmt.Printf("%s はセットされていません。\n", key)
	} else {
		fmt.Printf("%s=%s\n", key, val)
	}
}

出力

SETENV_MESSAGE=メッセージをセットします。
EMPTY_MESSAGE=
MISSING_MESSAGE はセットされていません。

というように、
代入が成功したら出力し、失敗したらエラーを返すという事が出来ます。

ExpandEnv(s string) string

ExpandEnvは、Setenvで設定した環境変数を含めて出力出来ます。

// Setenvで環境変数に設定します。
os.Setenv("SETENV_MESSAGE", "メッセージをセットします。")
os.Setenv("NAME", "エーイチ")

// $ を環境変数の前につけることで、ExpandEnvの中で使用出来ます.
message := os.ExpandEnv("$NAME は $SETENV_MESSAGE")

fmt.Println(message)

出力

エーイチ は メッセージをセットします。

さいごに

.envについて色々調べてみました。
Getenvだけじゃなくて、LookupEnvやExpandEnvを使いこなしたいと思いました。

もし間違っている箇所がありましたら、ご指摘頂けると幸いです。

Discussion

JboyHashimotoJboyHashimoto

こちらの記事参考になりました。こちらのコマンドを実行するとエラーが出てきましたが、使用しないでも.envの値は読み込めました。

go mod tidy # は不要だった?

error code

hashimotojunichi@hashimotojunichinoMacBook-Pro goenv % go mod tidy
go: warning: "all" matched no packages

go mod tidyを使用しなくても使うことができました。
ネットで調べてみると、go.mod ファイルがソースコードに合っているかを確認する。役割をしてくれるようですね。知らないコマンドだったので、とても勉強になりました。
https://developer.so-tech.co.jp/entry/2022/08/16/110108


私も勉強し始めたばかりなので、知識不足ですいません。