在zsh中放置$PATH变量声明的位置应该在哪里?

197

我喜欢使用zsh,但我不确定应该将我的$PATH和其他变量声明放在哪里?我发现它们分散在文件.zshrc.zprofile.bashrc.bash_profile中,并且有时会重复。

我意识到,在bash文件中放置任何内容都没有多大意义,因为我正在使用zsh,但是我应该把我的rvmpythonnode等添加到$PATH的地方放在哪里呢?

是否应该使用特定的文件(例如.zshenv,它目前不存在于我的安装中),我目前正在使用的文件之一,还是根本不要紧呢?

3个回答

262

简单来说,使用~/.zshrc

阅读man页面以了解以下文件之间的区别:

~/.zshrc~/.zshenv~/.zprofile


关于我的评论

在我附加到kev给出的答案的评论中,我说:

这似乎是不正确的 - 在任何我能找到的zsh文档中都没有列出 /etc/profile。

这部分是不正确的:/etc/profile 可能会被zsh引用。然而,这仅在zsh以“shksh”方式调用时发生;在这些兼容模式下:

通常的zsh启动/关闭脚本将不会被执行。登录shell按照/etc/profile后跟$HOME/.profile。如果在调用时设置了ENV环境变量,则在配置文件之后会执行$ENV。ENV的值会受到参数扩展、命令替换和算术扩展的影响,然后被解释为路径名。[man zshall,“Compatibility”]。

ArchWiki ZSH链接表示:

登录时,Zsh按以下顺序引用以下文件:
/etc/profile
所有兼容Bourne的shell都会在登录时引用该文件

这意味着/etc/profile在登录时总是被zsh读取 - 我没有使用过Arch Linux项目;对于那个发行版,维基可能是正确的,但这并不一般正确。与zsh手册页面相比,该信息不正确,似乎也不适用于OS X上的zsh(在/etc/profile中设置的$PATH路径无法到达我的zsh会话)。

回答问题:

我应该将rvm、python、node等添加到$PATH的哪个位置?

通常情况下,我会从~/.zshrc导出我的$PATH,但值得一读的是zshall手册页面,特别是“STARTUP/SHUTDOWN FILES”部分 - ~/.zshrc用于读取交互式shell,这可能适合你的需求,也可能不适合 - 如果您希望$PATH适用于由您调用的每个zsh shell(包括interactive和非interactive,包括login和非login等),那么~/.zshenv是一个更好的选择。

我应该使用特定的文件(例如我的安装中不存在的.zshenv),我目前正在使用的文件之一,还是根本无所谓?

有一堆在启动时读取的文件(检查链接的man页面),这也有其原因 - 每个文件都有其特定的位置(每个用户的设置、特定用户的设置、登录shell的设置、每个shell的设置等)。

不用担心 ~/.zshenv 不存在 - 如果你需要它,就创建它,然后它会被读取。

.bashrc.bash_profile 不会被 zsh 读取,除非你明确地从 ~/.zshrc 或类似的文件中包含它们;bashzsh 之间的语法并不总是兼容的。这两个文件都是为 bash 设置而设计的,而不是为 zsh 设置而设计的。


3
谢谢你的详细回答,simont。奇怪的是你说zsh不会读取.bashrc.bash_profile文件,因为我现在已经把我的rvm添加到了.bashrc中的$PATH,我的python添加到.bash_profile中,它们都被成功地添加了。无论如何,我要把所有的$PATH导出都移到~/.zshrc文件中,因为我所有其他zsh配置都在那里。我必须承认,我对不同类型的shell并不太熟悉。从阅读你发的链接中,我猜测我使用的是交互式shell,但我会进一步阅读以确认... 再次感谢! - stefmikhail
我在Ubuntu 20.04上遇到了zsh $PATH的问题,结果发现我的登录shell会读取~/.bashrc。这是因为在~/.profile中有一个检查,用于读取~/.bashrc的条件是if [ -n "$BASH_VERSION" ],而由于某种原因,我的zsh设置了该变量,因此条件为真。 - plafer

50

这里是来自zsh man页面的文档,在STARTUP/SHUTDOWN FILES部分。

   Commands  are  first  read from /etc/zshenv this cannot be overridden.
   Subsequent behaviour is modified by the RCS and GLOBAL_RCS options; the
   former  affects all startup files, while the second only affects global
   startup files (those shown here with an path starting with  a  /).   If
   one  of  the  options  is  unset  at  any point, any subsequent startup
   file(s) of the corresponding type will not be read.  It is also  possi-
   ble  for  a  file  in  $ZDOTDIR  to  re-enable GLOBAL_RCS. Both RCS and
   GLOBAL_RCS are set by default.

   Commands are then read from $ZDOTDIR/.zshenv.  If the shell is a  login
   shell,  commands  are  read from /etc/zprofile and then $ZDOTDIR/.zpro-
   file.  Then, if the  shell  is  interactive,  commands  are  read  from
   /etc/zshrc  and then $ZDOTDIR/.zshrc.  Finally, if the shell is a login
   shell, /etc/zlogin and $ZDOTDIR/.zlogin are read.

从这我们可以看出文件被读取的顺序是:

/etc/zshenv    # Read for every shell
~/.zshenv      # Read for every shell except ones started with -f
/etc/zprofile  # Global config for login shells, read before zshrc
~/.zprofile    # User config for login shells
/etc/zshrc     # Global config for interactive shells
~/.zshrc       # User config for interactive shells
/etc/zlogin    # Global config for login shells, read after zshrc
~/.zlogin      # User config for login shells
~/.zlogout     # User config for login shells, read upon logout
/etc/zlogout   # Global config for login shells, read after user logout file

你可以在这里获取更多信息。


22

我遇到了类似的问题(在bash终端命令运行正确,但是zsh显示命令未找到错误)。

解决方案:


只需将您之前在~/.bashrc中粘贴的内容粘贴到:

~/.zshrc

3
有趣的是,在 Mac 上,zsh 是默认 shell,但没有 .zshrc 文件,只有 .zprofile。大多数 Mac 工具和通过 brew 安装的实用程序仍然将配置放在 .bashrc 中,因此您必须手动复制它们。然而,更容易的方法是从 .zprofile 的末尾运行 .bashrc。 - John Little

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接