os.Getenv和os.LookupEnv不会返回$HISTFILE、$HISTSIZE和$SAVEHIST的值。

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

os.Getenv and os.LookupEnv don't return the value of $HISTFILE, $HISTSIZE, and $SAVEHIST

问题

我正在使用zsh,并尝试访问这些环境变量:

  1. $ echo $HISTFILE
  2. /home/amir/.zsh_history
  3. $ echo $HISTSIZE
  4. 50000
  5. $ echo $SAVEHIST
  6. 10000

但是,os.LookupEnv 对于这三个变量都返回 "", false,而 os.Getenv 自然地返回空字符串:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. func main() {
  7. histfile, found := os.LookupEnv("HISTFILE")
  8. if found {
  9. fmt.Println(histfile)
  10. } else {
  11. fmt.Println("$HISTFILE not found")
  12. }
  13. histsize, found := os.LookupEnv("HISTSIZE")
  14. if found {
  15. fmt.Println(histsize)
  16. } else {
  17. fmt.Println("$HISTSIZE not found")
  18. }
  19. savehist, found := os.LookupEnv("SAVEHIST")
  20. if found {
  21. fmt.Println(savehist)
  22. } else {
  23. fmt.Println("$SAVEHIST not found")
  24. }
  25. }
  1. $ go run main.go
  2. $HISTFILE not found
  3. $HISTSIZE not found
  4. $SAVEHIST not found

现在,如果我在$HOME/.zshrc中使用export导出这些变量:

  1. $ grep -iE "histfile|histsize|savehist" $HOME/.zshrc
  2. export HISTFILE="$HOME/.zsh_history"
  3. export HISTSIZE=1000000
  4. export SAVEHIST=1000000

然后它就可以工作了,并且返回了正确的值:

  1. $ go run hyst.go
  2. /home/amir/.zsh_history
  3. 1000000
  4. 1000000

当我没有显式导出这些变量时,$HISTSIZE$SAVEHIST的值是不同的,但它们不是空的。那么为什么这些函数对于这些变量返回空字符串呢?

英文:

I'm using zsh, and I'm trying to access these environment variables:

  1. $ echo $HISTFILE
  2. /home/amir/.zsh_history
  3. $ echo $HISTSIZE
  4. 50000
  5. $ echo $SAVEHIST
  6. 10000

But os.LookupEnv returns "", false for all three, and os.Getenv, naturally, returns an empty string:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. func main() {
  7. histfile, found := os.LookupEnv("HISTFILE")
  8. if found {
  9. fmt.Println(histfile)
  10. } else {
  11. fmt.Println("$HISTFILE not found")
  12. }
  13. histsize, found := os.LookupEnv("HISTSIZE")
  14. if found {
  15. fmt.Println(histsize)
  16. } else {
  17. fmt.Println("$HISTSIZE not found")
  18. }
  19. savehist, found := os.LookupEnv("SAVEHIST")
  20. if found {
  21. fmt.Println(savehist)
  22. } else {
  23. fmt.Println("$SAVEHIST not found")
  24. }
  25. }
  1. $ go run main.go
  2. $HISTFILE not found
  3. $HISTSIZE not found
  4. $SAVEHIST not found

Now, if I export these variables in $HOME/.zshrc:

  1. $ grep -iE "histfile|histsize|savehist" $HOME/.zshrc
  2. export HISTFILE="$HOME/.zsh_history"
  3. export HISTSIZE=1000000
  4. export SAVEHIST=1000000

Then it works and correct values are returned:

  1. $ go run hyst.go
  2. /home/amir/.zsh_history
  3. 1000000
  4. 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?

答案1

得分: 2

这是因为$HISTFILE$HISTSIZE$SAVEHIST默认情况下不是环境变量,而只是由oh-my-zsh设置的shell变量

  1. ## History file configuration
  2. [ -z "$HISTFILE" ] && HISTFILE="$HOME/.zsh_history"
  3. [ "$HISTSIZE" -lt 50000 ] && HISTSIZE=50000
  4. [ "$SAVEHIST" -lt 10000 ] && SAVEHIST=10000

这些是在使用export之前在$HOME/.zshrc中使用echo时看到的值。

重要的是要区分环境变量和shell变量

  • 环境变量可以在子进程中访问,但是shell变量不能。您可以通过创建一个子进程来验证这个说法:

    1. $ # 子进程不继承shell变量
    2. $ key=value; sh -c 'echo "key=$key"'
    3. key=
    4. $ # 但是,它们会继承环境变量
    5. $ export key=value; sh -c 'echo "key=$key"'
    6. key=value
  • 要在子进程中访问shell变量,您可以像在$HOME/.zshrc中那样使用export来导出它:

    1. $ key=value; export key; sh -c 'echo "key=$key"'
    2. key=value

现在,要查看特定变量是否是环境变量,而不是使用echo,您可以直接检查environment变量的列表。

  1. $ env | grep -i "shell"; echo $?
  2. SHELL=/usr/bin/zsh
  3. 0

所以$SHELL实际上是一个环境变量。现在来看看历史变量:

  1. $ env | grep -iE "histfile|histsize|savehist"; echo $?
  2. 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:

  1. ## History file configuration
  2. [ -z "$HISTFILE" ] && HISTFILE="$HOME/.zsh_history"
  3. [ "$HISTSIZE" -lt 50000 ] && HISTSIZE=50000
  4. [ "$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:

    1. $ # Child processes don't inherit shell variables
    2. $ key=value; sh -c 'echo "key=$key"'
    3. key=
    4. $ # They do, however, inherit environment variables
    5. $ export key=value; sh -c 'echo "key=$key"'
    6. key=value
  • To be able to access a shell variable in the child process, you can export it, just as you did in $HOME/.zshrc:

    1. $ key=value; export key; sh -c 'echo "key=$key"'
    2. 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.

  1. $ env | grep -i "shell"; echo $?
  2. SHELL=/usr/bin/zsh
  3. 0

So $SHELL is, in fact, an environment variable. Now for the history variables:

  1. $ env | grep -iE "histfile|histsize|savehist"; echo $?
  2. 1

The exit code is 1, meaning that it failed to find these names in the list of environment variables.

huangapple
  • 本文由 发表于 2022年4月26日 14:45:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/72009448.html
匿名

发表评论

匿名网友

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

确定