如何在zsh中添加永久环境变量

我已经在互联网上搜索了很久,但似乎找不到一个永久添加环境变量的解决方案,特别是在我的 macOS Mojave(10.14)操作系统上。似乎有很多针对该操作系统旧版本的教程,但没有针对这个版本的教程。同时,所有旧方法似乎都已过时。

我想要将一个环境变量 ENV_VAR=12345 添加到我的 Mac 上,以便我可以在 Python 模块中使用 os.environ['ENV_VAR'] 进行导入。

我找到的最相关的教程是 this,但它对我来说并不完全适用。很多其他教程告诉你如何临时向 bash 添加环境变量,但我觉得这还不够。我希望在重新启动终端后仍然存在这个添加的环境变量。

请您提供一个简短的教程,或者指点我正确/现代的教程。

更新:我应该提到我使用的是 zsh。这一点很关键。


请查看https://unix.stackexchange.com/questions/346336/why-have-both-bash-profile-and-bashrc和/或https://unix.stackexchange.com/questions/48870/global-bash-profile以持久化环境变量。 - tk421
这个Python脚本是从命令行运行还是作为桌面或Finder中的应用程序运行? - mmmmmm
@Mark 脚本是从命令行运行的!通过 python -m module_name - Intrastellar Explorer
我投票关闭这个问题,因为问题不清楚,提到的是zsh shell,但没有明确说明。教程等内容是针对不同情况的。如果问题是关于如何在使用zsh时设置Python环境变量,那就没问题。问题和答案只会让新读者感到困惑。 - mmmmmm
7个回答

Bash

由于Bash通常是默认的shell,您可以在您的主目录中打开此文件:

$ vim ~/.bash_profile

并将您的变量添加到此文件中:

export ENV_VAR=12345

如果你愿意的话,甚至无需编辑此文件,只需使用以下一行命令即可完成。
$ echo 'export ENV_VAR=12345' >> ~/.bash_profile

然后就这样确认:
$ cat ~/.bash_profile
for i in ~/.bash_profile.d/[0-9]*; do
  . "$i"
done
export ENV_VAR=12345

完成上述操作后,如果您打开一个新的终端,您应该能看到环境变量已经设置成功。
$ echo $ENV_VAR
12345

如果你发现自己正在使用一种替代的shell,比如zsh,它使用一组不同的配置文件来维护你的主目录(~)中。幸运的是,更改的语法基本相同,只是文件不同而已。所以你可以将上面的示例添加到这个文件中:
$ echo 'export ENV_VAR=12345' >> ~/.zshenv

然后当你启动一个zsh时:
$ echo $ENV_VAR
12345

参考资料


注意:如果您希望在不通过shell上下文启动的情况下访问ENV,例如直接运行Python脚本时,在bash/zsh配置文件中设置它将无法解决问题。您需要使用launchctl setenv ENV_NAME ENV_VALUE使其在任何地方都可用。有关更多信息,请参阅我的其他答案。 - Chris
1在MacOS Monterey中,我在用户目录和/etc下都没有zshenv。因此,我使用$ echo 'export ENV_VAR=12345' >> ~/.zshrc来注入这个环境变量。 - Zhou Haibo

首先,在终端中使用zsh(Z Shell)执行以下命令:
echo 'export ENV_VAR=12345' >> ~/.zshenv

然后,重新加载更改:
source ~/.zshenv

最后,测试一下你的新变量是否已经设置好了:
echo $ENV_VAR

注意: 按照标准,.zshenv文件应只包含环境变量设置命令。.zshenv文件在每次调用shell时都会被引用,因此即使在重新启动机器后,它仍然会保持不变。

1可能对专家来说有点显而易见,但是source命令对我起到了作用,甚至我都不需要重新打开另一个终端。(与被接受的答案相反) - Jelle

其他解决方案描述了如何在所有的zsh/bash shell实例中设置环境变量。但是它们没有设置一个永久的环境变量,该变量可以在macOS的任何地方使用,包括在每个启动的程序中。
例如,如果你在你的.zshrc文件中定义了ENV_VAR=1,但是直接从终端启动Python而不是从shell启动它,那么在os.environ['...']中设置的任何内容都无法使用。
为了解决这个问题,你可以使用launchctl在macOS的系统级别上设置一个真正的全局环境变量,方法如下:
launchctl setenv "ENV_VAR" "12345"

运行后,每个新启动的程序将看到包括shell实例在内的ENV_VAR环境变量,以及无需使用shell启动的内容。您需要关闭终端应用并重新打开才能在shell中生效。它也不会显示在ssh会话中,因为ssh会话不是由launchd像GUI程序一样启动。
更新:似乎这在系统重启后不会持续存在。你可以在这里找到一些讨论here。有趣的是,解决方法之一就是在你的shell的.zshenv.bash_profile中加入launchctl setenv ...。尽管这意味着你需要在全局变量设置之前启动一个shell,所以你可以在这里看到一些更加健壮的解决方案robust solutions that involve creating a new launchd job here

显示所有隐藏文件,如 .bash_profile 和 .zshrc $ ls -a

从 macOS Catalina 开始,新创建的帐户在 macOS 中使用 zsh 而不是 bash。

检查当前正在运行的 shell:

$ echo $SHELL
/usr/zsh

$ cd $HOME
$ open -e .zshrc

或者如果使用vim
$ vi .zshrc

然后像这样添加它。
$ export my_var="/path/where/it/exists"
$ export PATH=$PATH:/$my_var/bin

例如:如果已安装名为 myapp 的应用程序在 /Applications 中,则
export MYAPP_HOME=/Applications/myapp
export PATH=$PATH:$MYAPP_HOME/bin

或者捷径
export PATH=${PATH}:/Applications/myapp/bin

就我所知,我使用this便携式shell function来快速设置永久添加环境变量
我主要使用zsh,但它可以很容易地适应bash或其他符合POSIX标准的shell。
# -----------------------------------------
#  Create permanent environment variable
#
#  $1 - variable name
#  $2 - variable definition
#  @requires: '~/.zshrc' or '~/.bashrc'
# -----------------------------------------
function new_env_var {
  local detected_shell="$(ps -o comm= -p $$)"
  local rcfile=$(echo "${HOME}/.${detected_shell//-/}rc")
  if [[ -f $rcfile ]]; then
    local var_name; local var_val
    if [ -z "$1" ]; then
      echo "variable name (e.g. 'NEW_VAR' for '\$NEW_VAR'):"; read var_name
    else
      var_name=$1
    fi
    if [ -z "$2" ]; then
      echo "variable definition:"; read var_val
    else
      local s2 var_val="${@//${var_name}/}"
      until s2="${var_val#[   ]}"; [ "$s2" = "$var_val" ]; do var_val="$s2"; done
    fi
    echo "export $var_name=\"$var_val\"" >> $rcfile; export $var_name="$var_val"
  else
    echo "No $detected_shell runcom file found. Please make sure $rcfile exists."
  fi
}

你可以这样使用: ‣ new_env_var MY_ENV_VAR 9,999

设置环境变量所使用的文件名取决于您使用的是哪个 shell。默认情况下,Mac 会将 bash shell 分配给新用户。如果不确定,请使用 echo $SHELL

从这里开始,查看 man 页面。例如:man bash,它会记录运行时执行的文件。您可以将环境变量添加到其中一个文件中。

对于 bash,请确保您 export 变量,否则子进程不会继承该变量。例如:export ENV_VAR=12345ENV_VAR=12345; export ENV_VAR


更新:阅读@slm回答下的评论。我应该编辑~/.zshrc而不是~/.bash_profile,因为我使用的是zsh。知道得越多越好!以下答案似乎也有效,但有点糟糕。
感谢 @Tim Campbell 和 @slm,我成功地让某些东西运作起来了。
背景: echo $0 输出 -zsh echo $SHELL 输出 /bin/zsh echo $PATH 输出 /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
我的“Hacky”解决方案
我创建了一个名为`configure_env.sh`的shell脚本,并将其放在`~/Documents`目录中。
#!/bin/zsh
export ENV_VAR=12345

我接着运行了chmod +x ~/Documents/configure_env.sh 然后我执行了nano ~/.bash_profile并追加了source ~/Documents/configure_env.sh 然后,当我输入echo $ENV_VAR时,它返回了12345 :) 再次感谢 Stack Overflow!

3哎呀,这真是一团糟,而且是个可怕的主意——你只需要编辑一个文件,并在其中添加export ENV_VAR=12345,该文件名为.zshrc。所以,在我使用zsh之后,删除所有内容。另外,你使用zsh的事实必须在问题中提到。 - mmmmmm