在Go程序退出后,在shell上持久保存环境变量的值。

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

Persist the value set for an env variable on the shell after the go program exits

问题

你好!以下是翻译好的内容:

有没有办法在我的 shell 上设置一个环境变量,并在 go 程序退出后保持不变?我尝试了以下操作:

bash-3.2$ export WHAT=am
bash-3.2$ echo $WHAT
am

bash-3.2$ go build tt.go 
bash-3.2$ ./tt
am
is your name
bash-3.2$ echo $WHAT
am
bash-3.2$ 

代码如下:

package main
import (
        "fmt"
        "os"
)

func main() {
fmt.Println(os.Getenv("WHAT"))
os.Setenv("WHAT", "is your name")
fmt.Println(os.Getenv("WHAT"))
}

希望对你有帮助!

英文:

Is there a way i can set an Environment variable on my shell and have it persist after the go program exits ? I tried the following

bash-3.2$ export WHAT=am
bash-3.2$ echo $WHAT
am

bash-3.2$ go build tt.go 
bash-3.2$ ./tt
am
is your name
bash-3.2$ echo $WHAT
am
bash-3.2$ 

The code was :

package main`
import (
        "fmt"
       "os"`
)

func main() {
fmt.Println(os.Getenv("WHAT"))
os.Setenv("WHAT", "is your name")
fmt.Println(os.Getenv("WHAT"))
}

Thanks

答案1

得分: 12

不,环境变量只能向下传递,不能向上传递。你正在尝试做后者。

你的进程树:

`--- shell
          `--- go程序
          |
          `--- 其他程序

go程序必须将环境变量传递给shell,以便其他程序可以访问它。

你可以像ssh-agent这样的程序那样做:返回一个可以解释为设置环境变量的字符串,然后由shell进行评估。

例如:

func main() {
    fmt.Println("WHAT='is your name'")
}

运行它会得到:

$ ./goprogram
WHAT='is your name'

评估打印出的字符串会产生你想要的效果:

$ eval `./goprogram`
$ echo $WHAT
is your name
英文:

No, environment variables can only be passed down, not up. You're trying to do the latter.

Your process tree:

`--- shell
          `--- go program
          |
          `--- other program

The go program would have to pass the environment variable up to the shell so that the other program can access it.

What you can do is what programs like ssh-agent do: return a string that can be interpreted as setting a environment variable which can then be evaluated by the shell.

For example:

func main() {
    fmt.Println("WHAT='is your name'")
}

Running it will give you:

$ ./goprogram
WHAT='is your name'

Evaluating the printed string will give you the desired effect:

$ eval `./goprogram`
$ echo $WHAT
is your name

答案2

得分: 1

不。

一个进程拥有其父进程的环境的副本,无法写入父进程的环境。

英文:

No.

A process has a copy of its parent's environment and can't write to the parent environment.

答案3

得分: 0

其他答案都是正确的,但是你可以自由地执行你的 Golang 代码,将任意值填充到环境变量中,并将其输出到你的 Golang 创建的输出文件中,然后在执行该 Golang 二进制文件的父环境中,通过源文件的方式来使用 Golang 的输出文件,从而在你的 Golang 代码内计算环境变量... 这可以是你的 Golang 代码 write_to_file.go

package main

import (
    "io/ioutil"
)

func main() {
    
    d1 := []byte("export whodunit=calculated_in_golang\n")
    if err := ioutil.WriteFile("/tmp/cool_file", d1, 0644); err != nil {
        panic(err)
    }
}

现在将上述 write_to_file.go 编译成二进制文件 write_to_file... 这里是一个作为父进程执行上述二进制文件的 Bash 脚本:

#!/bin/bash

whodunit=aaa

if [[ -z $whodunit ]]; then

    echo 变量 whodunit 没有值
else

    echo 变量 whodunit 的值为 $whodunit
fi

./write_to_file # <-- 在这里执行 Golang 二进制文件,它会在输出文件 /tmp/cool_file 中填充一个导出的变量

curr_cool=/tmp/cool_file

if [[ -f $curr_cool ]]; then # 如果文件存在

    source /tmp/cool_file # shell 可以区分 sourcing shell 和执行 shell,sourcing 不会切换到子 shell,它在父环境中执行
fi

if [[ -z $whodunit ]]; then

    echo 变量 whodunit 仍然没有值
else

    echo 变量 whodunit 最终的值为 $whodunit
fi

以下是执行上述 Shell 脚本的输出:

变量 whodunit 的值为 aaa
变量 whodunit 最终的值为 calculated_in_golang
英文:

The other answers are strictly correct, however you are free to execute your golang code to populate arbitrary values to environment variables into an output file your go creates then back in the parent environment from which you executed that go binary then source the go's output file to have available env variables calculated from inside your go code ... this could be your go code write_to_file.go

package main

import (
    &quot;io/ioutil&quot;
)

func main() {
	
    d1 := []byte(&quot;export whodunit=calculated_in_golang\n&quot;)
    if err := ioutil.WriteFile(&quot;/tmp/cool_file&quot;, d1, 0644); err != nil {
    	panic(err)
    }
}

now compile above write_to_file.go into binary write_to_file ... here is a bash script which can act as the parent to execute above binary

#!/bin/bash

whodunit=aaa

if [[ -z $whodunit ]]; then

	echo variable whodunit has no value
else

	echo variable whodunit has value $whodunit
fi

./write_to_file # &lt;-- execute golang binary here which populates an exported var in output file /tmp/cool_file

curr_cool=/tmp/cool_file

if [[ -f $curr_cool ]]; then # if file exists

	source /tmp/cool_file # shell distinguishes sourcing shell from executing, sourcing does not cut a subshell it happens in parent env
fi

if [[ -z $whodunit ]]; then

    echo variable whodunit still has no value 
else

    echo variable whodunit finally has value $whodunit
fi

here is the output from executing above shell script

variable whodunit has value aaa
variable whodunit finally has value calculated_in_golang

huangapple
  • 本文由 发表于 2016年3月18日 10:01:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/36074851.html
匿名

发表评论

匿名网友

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

确定