How to set environment variables that last

huangapple go评论80阅读模式
英文:

How to set environment variables that last

问题

我正在尝试使用Go OS在我的机器上设置一些环境变量。

err := os.Setenv("DBHOST", dbHostLocal)
if err != nil {
	log.Fatalf("err %v", err)
}

看起来这个变量在Go程序中是可用的,但是一旦我退出/终止Go进程,该变量就不再可用了。我想知道是否可能永久设置这些变量。原因是我想创建一个包含配置文件(数据库名称等)的“设置”文件,用于本地和开发环境之间的切换,而无需进行任何设置... 只需运行一次 go run setup.go。

英文:

I'm trying to set some environment variables on my machine using Go OS

	err := os.Setenv("DBHOST", dbHostLocal)
	if err != nil {
		log.Fatalf("err %v", err)
	}

It seems the variable is available to the Go program but once I quite / terminate the Go process the variable is no longer available. I'm wondering if it's possible to set these variables permanently. The reason is that i was looking to create a "setup" file with config files ( db name etc ) for the local and dev environment so that I could switch between without any setup at all... just one time go run setup.go.

答案1

得分: 23

不可能的。你不能改变父进程的环境。你只能改变自己的环境并将其传递给子进程。

你应该维护一个配置文件。
有很多Go的配置库可供选择:ini、yaml等。

如果你的程序更改了配置,每次更改后或者在一段时间后或者进程退出时将其保存到磁盘上。

英文:

Short: It is not possible. You can't change the environment of your parent process. You can only change your own and pass it to your children.

What you should do is maintain a config file.
There are plenty of go config libs out there: ini, yaml, etc.

If your program changes the config, save it to disk after each change or one in a while or when the process exits.

答案2

得分: 11

虽然被认为不可能,但如果你正在构建一个退出的命令行工具,你可以考虑将等效的 shell 输出到 STDOUT,例如:docker-machine eval。

以下是一个简单的示例:

package main

import (
  "fmt"
  "reflect"
  "strings"
)

type config struct {
  db_host string
  db_port int
  db_user string
}

func main() {
  c := config{"db.example.com", 3306, "user1"}

  ct := reflect.ValueOf(&c).Elem()
  typeOfC := ct.Type()

  for i := 0; i < ct.NumField(); i++ {
    f := ct.Field(i)
    fmt.Printf("%s=%v\n", strings.ToUpper(typeOfC.Field(i).Name), f)
  }
}

输出结果:

$ go run env.go
DB_HOST=db.example.com
DB_PORT=3306
DB_USER=user1

然后你可以在命令行上使用eval命令,并访问这些变量。

$ eval $(go run env.go)
$ echo $DB_HOST
db.example.com
英文:

Whilst not considered possible, if you're building some cli tool that exits you could consider outputting the equivalent shell to STDOUT like: docker-machine eval.

Quick and dirty example:

package main

import (
  &quot;fmt&quot;
  &quot;reflect&quot;
  &quot;strings&quot;
)

type config struct {
  db_host string
  db_port int
  db_user string
}

func main() {
  c := config{&quot;db.example.com&quot;, 3306, &quot;user1&quot;}

  ct := reflect.ValueOf(&amp;c).Elem()
  typeOfC := ct.Type()

  for i := 0; i &lt; ct.NumField(); i++ {
    f := ct.Field(i)
    fmt.Printf(&quot;%s=%v\n&quot;, strings.ToUpper(typeOfC.Field(i).Name), f)
  }
}

Output:
$ go run env.go
DB_HOST=db.example.com
DB_PORT=3306
DB_USER=user1

You can then eval it on the command line and have access to those variables.

$ eval $(go run env.go)
$ echo $DB_HOST
db.example.com

答案3

得分: 3

唯一实现你想要的行为的方法是修改当前 shell 的环境,而最简单的方法是使用一个简单的 shell 脚本。

# setup.sh
export DBHOST="dbhost.url"
export CONFIG_VAR_TWO="testing"

然后执行以下命令:

$ source setup.sh
英文:

The only way to get the behavior you want is to alter the environment of the current shell, and the easiest way is with a simple shell script

# setup.sh
export DBHOST=&quot;dbhost.url&quot;
export CONFIG_VAR_TWO=&quot;testing&quot;

and then

$ source setup.sh

答案4

得分: 1

如果你想要写入注册表的值,是有可能的,但是你的应用程序需要管理员权限。

func setEnvironment(key string, value string){
   k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\ControlSet001\Control\Session Manager\Environment`, registry.ALL_ACCESS)
   if err != nil {
       log.Fatal(err)
   }
   defer k.Close()

   err = k.SetStringValue(key, value)
   if err != nil {
       log.Fatal(err)
   }
}
英文:

It's possible if you write a value to the registry, but for this, your application needs administrator rights

func setEnvironment(key string, value string){
   k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\ControlSet001\Control\Session Manager\Environment`, registry.ALL_ACCESS)
   if err != nil {
	   log.Fatal(err)
   }
   defer k.Close()

   err = k.SetStringValue(key, value)
   if err != nil {
	   log.Fatal(err)
   }
}

huangapple
  • 本文由 发表于 2014年7月25日 00:11:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/24938877.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定