Viper 自动环境不从环境中读取

问题描述 投票:0回答:2

我正在尝试完成一个非常简单的示例,其中我使用

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("Unable to load config: %s\n", err)
    }

    fmt.Printf("%+v\n", &config)
}

我正在设置环境变量来尝试测试环境变量名称的不同排列

MY_STRING=a my_string=b MyString=c ./viper-demo

我尝试了很多不同的方法,删除

mapstructure
注释,更改其值等,但执行时得到的只是:

&{MyString:}

我正在按照自述文件以及我在网上找到的其他演示中的说明进行操作,但看起来

viper
没有加载环境变量。

我觉得这是一个非常简单的示例,我的要求是将配置映射到结构,并从环境变量中获取该配置。我最终可能会开始做 CLI 标志和配置文件,但环境变量对我来说是成败的,我需要它们工作。

我错过了什么?

go environment-variables viper-go
2个回答
3
投票

这似乎是一个长期存在的问题,已经持续了好几年了[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)
}
  1. https://github.com/spf13/viper/issues/188
  2. https://pkg.go.dev/github.com/spf13/viper#Viper.BindEnv
  3. https://golang.org/pkg/os#Environ

0
投票

自 2023 年 12 月起已合并修复程序。您必须通过 [1] 启用该功能,例如:

go build -tags=viper_bind_struct ...

  1. https://github.com/spf13/viper/pull/1429#issuecomment-1870976604
© www.soinside.com 2019 - 2024. All rights reserved.