Hello, this is my first post at DEV.TO đļ
To get the list of all environment variables in Go, I found a function to do that in standard libraries
Environ returns a copy of strings representing the environment, in the form "key=value".
Using this function, I tried to write a function to get all environment variables key-value pairs in map[string]string
.
Bad example đŖ
I at first wrote following code.
kv := os.Environ()
m := make(map[string]string, len(kv))
for _, s := range kv {
if idx := strings.IndexRune(s, '='); idx >= 0 {
m[s[:idx]] = s[idx+1:]
}
}
// `m` is what I wanted!
This example looked working fine at first, however later I found in some case it did not work only on Windows.
I found that the m
contains empty string key ""
and checked the output from os.Environ()
line by line. And finally I found the cause.
=C:=C:\path\to\current\dir
What's this? But environment variable $=C:
was actually existing on system. It was a hidden environment variable not listed in output of set
command.
I dug Go standard library and found a comment (thank you @mattn for helping me to find out this!).
Environment variables can begin with =
so start looking for the separator = at j=1.
https://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
The post in the comment, What are these strange =C: environment variables? explained what $=C:
is.
Okay, so the command processor sets these things, but what are they? They are a leftover from the command processor's attempt to mimic the old MS-DOS way that drives and directories were handled. Whereas in Win32, there is only one current directory, in MS-DOS, there was one current directory for each drive.
So this is a hidden special environment variable on Windows and I need to consider it on getting all environment variables.
Good example đ
Fortunately, fix was easy. =
is at first character, and environment variable name is never empty. So we can simply ignore the first character.
kv := os.Environ()
m := make(map[string]string, len(kv))
for _, s := range kv {
// On Windows, environment variable names may start with '=' (e.g. =C:).
// To handle the variables properly, skip first character of KEY=VALUE line.
for i := 1; i < len(s); i++ {
if s[i] == '=' {
m[s[:i]] = s[i+1:]
break
}
}
}
// `m` is what I wanted!
Top comments (0)