'os.Getenv and os.LookupEnv don't return the value of $HISTFILE, $HISTSIZE, and $SAVEHIST
I'm using zsh, and I'm trying to access these environment variables:
$ echo $HISTFILE
/home/amir/.zsh_history
$ echo $HISTSIZE
50000
$ echo $SAVEHIST
10000
But os.LookupEnv returns "", false for all three, and os.Getenv, naturally, returns an empty string:
package main
import (
"fmt"
"os"
)
func main() {
histfile, found := os.LookupEnv("HISTFILE")
if found {
fmt.Println(histfile)
} else {
fmt.Println("$HISTFILE not found")
}
histsize, found := os.LookupEnv("HISTSIZE")
if found {
fmt.Println(histsize)
} else {
fmt.Println("$HISTSIZE not found")
}
savehist, found := os.LookupEnv("SAVEHIST")
if found {
fmt.Println(savehist)
} else {
fmt.Println("$SAVEHIST not found")
}
}
$ go run main.go
$HISTFILE not found
$HISTSIZE not found
$SAVEHIST not found
Now, if I export these variables in $HOME/.zshrc:
$ grep -iE "histfile|histsize|savehist" $HOME/.zshrc
export HISTFILE="$HOME/.zsh_history"
export HISTSIZE=1000000
export SAVEHIST=1000000
Then it works and correct values are returned:
$ go run hyst.go
/home/amir/.zsh_history
1000000
1000000
When I haven't explicitly exported these variables, the values of $HISTSIZE and $SAVEHIST are different, but they're not empty. So why do these functions return empty strings for these variables?
Solution 1:[1]
That's because $HISTFILE, $HISTSIZE, and $SAVEHIST are not, by default, environment variables, but rather simply shell variables set by oh-my-zsh:
## History file configuration
[ -z "$HISTFILE" ] && HISTFILE="$HOME/.zsh_history"
[ "$HISTSIZE" -lt 50000 ] && HISTSIZE=50000
[ "$SAVEHIST" -lt 10000 ] && SAVEHIST=10000
These are the values you see when you use echo before using export in $HOME/.zshrc.
It's important to make a distinction between environment and shell variables:
Environment variables are accessible in child processes, but shell variables are not. You can verify this statement by simply creating a child process:
$ # Child processes don't inherit shell variables $ key=value; sh -c 'echo "key=$key"' key= $ # They do, however, inherit environment variables $ export key=value; sh -c 'echo "key=$key"' key=valueTo be able to access a shell variable in the child process, you can
exportit, just as you did in$HOME/.zshrc:$ key=value; export key; sh -c 'echo "key=$key"' key=value
Now, to see if a specific variable is an environment variable or not, instead of using echo, you can directly check the list of environment variables.
$ env | grep -i "shell"; echo $?
SHELL=/usr/bin/zsh
0
So $SHELL is, in fact, an environment variable. Now for the history variables:
$ env | grep -iE "histfile|histsize|savehist"; echo $?
1
The exit code is 1, meaning that it failed to find these names in the list of environment variables.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Amir Shabani |
