0

In vanilla go, it seems pretty trivial to set an environment variable. The os library has a Setenv function that should get the job done. I'm running into trouble doing that inside of a cobra command. Is there a simple way that I'm missing, or is this functionality not supported at this point?

Example of what I'm trying to do:

package main

import (
    "fmt"
    "os"

    "github.com/spf13/cobra"
    "github.com/spf13/pflag"

    "k8s.io/cli-runtime/pkg/genericclioptions"
)

func main() {
    flags := pflag.NewFlagSet("ex-com", pflag.ExitOnError)
    pflag.CommandLine = flags

    root := newCmdEx(genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr})
    if err := root.Execute(); err != nil {
        fmt.Fprintf(os.Stdout, "Error: %[1]s", err.Error())
        os.Exit(1)
    }
    os.Exit(0)
}

type ExOpOptions struct {
    configFlags genericclioptions.ConfigFlags
}

func NewExOpOptions(streams genericclioptions.IOStreams) *ExOpOptions {
    return &ExOpOptions{}
}

func newCmdEx(streams genericclioptions.IOStreams) *cobra.Command {
    o := NewExOpOptions(streams)

    cmd := &cobra.Command{
        RunE: func(c *cobra.Command, args []string) error {
            return o.Run()
        },
    }

    o.configFlags.AddFlags(cmd.Flags())

    return cmd
}

func (o *ExOpOptions) Run() error {
    return os.Setenv("THEBESTOFTIMES", "Sure it was.")
}

Example build and test script:

GO111MODULE="on" go build cmd/ex-com.go && \
   echo "First Print:" && \
   echo "$THEBESTOFTIMES" && \
   ./ex-com && \
   echo "Second Print:" && \
   echo "$THEBESTOFTIMES"

I would expect the output to look like this (since the environment variable is being set on line 48 of the go code):

go: finding k8s.io/cli-runtime/pkg/genericclioptions latest
go: finding k8s.io/cli-runtime/pkg latest
go: finding k8s.io/cli-runtime latest
First Print:

Second Print:
Sure it was.

But currently it looks like this:

go: finding k8s.io/cli-runtime/pkg/genericclioptions latest
go: finding k8s.io/cli-runtime/pkg latest
go: finding k8s.io/cli-runtime latest
First Print:

Second Print:

distortedsignal
  • 370
  • 5
  • 17
  • 1
    It looks like you're expecting to see the environment variable set in the program after program terminates. That is not possible. Environment is copied when a program is executed, and changes made to that environment will stay local to the executed program and its children. Changes will not be visible to the shell that started the program. – Burak Serdar Sep 04 '19 at 22:30
  • Thanks @bserdar - I've voted you up, and I think that this is the correct answer. I'll keep the question around so that future generations can witness my failure. If this changes in the future, I hope someone answers this question. – distortedsignal Sep 04 '19 at 23:22

0 Answers0