英文:
Viper Automatic Environment Does Not Read from Environment
问题
我正在尝试完成一个非常简单的示例,其中我使用viper
从环境变量中加载配置。我已经通过go get github.com/spf13/viper
在我的项目中安装了它,并且依赖项在我的go.mod
文件中:
module github.com/naftulikay/viper-demo
go 1.16
require github.com/spf13/viper v1.7.1 // indirect
以下是我的代码,它可以编译和运行:
package main
import (
"fmt"
"github.com/spf13/viper"
)
var config Config
type Config struct {
MyString string //`mapstructure:"MY_STRING"`
}
func main() {
v := viper.New()
v.AutomaticEnv()
var err error
err = v.Unmarshal(&config)
if err != nil {
fmt.Printf("无法加载配置:%s\n", err)
}
fmt.Printf("%+v\n", &config)
}
我正在设置环境变量来尝试测试环境变量名称的不同排列组合:
MY_STRING=a my_string=b MyString=c ./viper-demo
我尝试了很多不同的方法,删除了mapstructure
注释,更改了它的值等等,但是当我执行时,我得到的只是:
&{MyString:}
我正在按照自述文件以及我在网上找到的其他演示进行操作,但似乎viper
不会加载环境变量。
我觉得这是一个非常简单的示例,我的要求是将配置映射到一个结构体,并从环境变量中获取该配置。我可能最终会开始使用CLI标志和配置文件,但对我来说,环境变量是必不可少的,我需要它们正常工作。
我漏掉了什么?
英文:
I'm trying to complete a very simple example wherein I use viper
to load configuration from environment variables. I have installed it in my project via go get github.com/spf13/viper
, and the dependency is in my go.mod
:
module github.com/naftulikay/viper-demo
go 1.16
require github.com/spf13/viper v1.7.1 // indirect
Here is my code, which does compile and run:
package main
import (
"fmt"
"github.com/spf13/viper"
)
var config Config
type Config struct {
MyString string //`mapstructure:"MY_STRING"`
}
func main() {
v := viper.New()
v.AutomaticEnv()
var err error
err = v.Unmarshal(&config)
if err != nil {
fmt.Printf("Unable to load config: %s\n", err)
}
fmt.Printf("%+v\n", &config)
}
I am setting environment variables to try to test different permutations of the environment variable name
MY_STRING=a my_string=b MyString=c ./viper-demo
I've tried a lot of different things, removing the mapstructure
annotation, changing its value, etc., but all I get when I execute is:
&{MyString:}
I'm following the instructions from the README as well as other demos I've found online and it just seems like viper
does not load environment variables.
I feel like this is a very simple example, my requirements are mapping config to a struct, and fetching that config from environment variables. I may eventually start doing CLI flags and a config file, but environment variables are make-or-break for me, I need them to work.
What am I missing?
答案1
得分: 2
这似乎是一个长期存在的问题,已经有几年了[1]。然而,在那个讨论中建议可以使用BindEnv
[2]:
package main
import (
"fmt"
"github.com/spf13/viper"
)
func main() {
var c struct {
TMP string
}
v := viper.New()
v.AutomaticEnv()
v.BindEnv("TMP")
v.Unmarshal(&c)
fmt.Printf("%+v\n", &c)
}
另一种方法是使用os.Environ
[3]:
package main
import (
"fmt"
"os"
"strings"
)
func environ() map[string]string {
m := make(map[string]string)
for _, s := range os.Environ() {
a := strings.Split(s, "=")
m[a[0]] = a[1]
}
return m
}
func main() {
m := environ()
fmt.Printf("%q\n", m)
}
- https://github.com/spf13/viper/issues/188
- https://pkg.go.dev/github.com/spf13/viper#Viper.BindEnv
- https://golang.org/pkg/os#Environ
英文:
This seems to be a long running issue, for several years now [1]. However, in
that thread it is suggested that you can use BindEnv
[2]:
package main
import (
"fmt"
"github.com/spf13/viper"
)
func main() {
var c struct {
TMP string
}
v := viper.New()
v.AutomaticEnv()
v.BindEnv("TMP")
v.Unmarshal(&c)
fmt.Printf("%+v\n", &c)
}
For another approach, you can use os.Environ
[3]:
package main
import (
"fmt"
"os"
"strings"
)
func environ() map[string]string {
m := make(map[string]string)
for _, s := range os.Environ() {
a := strings.Split(s, "=")
m[a[0]] = a[1]
}
return m
}
func main() {
m := environ()
fmt.Printf("%q\n", m)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论