macOS 环境变量加载探究

使用 macOS 安装环境,见到过很数种环境变量配置方法,每次也都是按照别人的代码,人家配置在哪 我就配置在哪,其实不太清楚有什么区别,决定记录下。

  • 本机 macOS 13.3,从 macOS Catalina(10.15) 开始,macOS的默认终端从bash变成了zsh ,所以在网上经常看到的 ~/.bash_profile 事实上是无法生效的,应该修改 ~/.zshrc
  • 我们常说的环境变量修改有两种方式,分为系统级别(对所有用户生效)和用户级别(对当前用户生效),像 /etc/profile 这种在 /etc 目录下的配置则都属于全局配置,~/ 则属于用户级别的,当然 macOS 也不是服务器,一般就自己一个人用,也不用分得太清楚。

系统级别

  1. /etc/profile 文件
    • 语法格式:采用 Shell 命令语法
    • 加载时间:系统启动时加载,更新重启生效。
    • 不建议修改,最好在用户级别的配置文件中进行个性化设置。
  2. /etc/paths 文件:路径格式,在系统启动时,这些路径会被添加到全局的$PATH环境变量的前面,影响所有用户和进程。
    • 语法格式:每行一个路径,没有特定的语法格式。
    • 加载时间:系统启动时加载,更新重启生效【但本机实测更新后,打开新终端窗口能够生效,不确定】。
    • 加载原理:系统启动时,其中的路径会被添加到系统的 $PATH 环境变量的前面
    • 全局环境变量建议修改这个文件。
    • macOS 特供(/etc/paths.d/同),在 Linux 系统中通常不是标准配置,Linux 通常使用 /etc/profile/etc/environment
  3. /etc/paths.d/ 目录:这个目录中可以放置其他路径设置的文件,每个文件包含一行一个路径。同样在系统启动时,这些路径会被添加到全局的$PATH环境变量的前面,影响所有用户和进程。
    • 语法格式:每个文件包含一组路径,没有特定的语法格式。
    • 加载时间:系统启动时加载。
    • 加载原理:/etc/profile 脚本中有一行 eval `/usr/libexec/path_helper -s,这个path_helper工具会读取/etc/paths.d目录下的文件里面的路径,然后加载在环境变量$PTAH

/etc/paths vs /etc/paths.d

  • macOS 系统升级时,/etc/paths文件在系统升级时可能会被覆盖或修改【不过事实上,我一年多以前配的路径现在还活的好好的,中间经历过一次大版本,数次小版本更新】,导致用户的自定义路径设置丢失,而/etc/paths.d/目录下的路径配置通常不会受到影响。

  • 模块化:如果一个软件需要将自己的可执行文件路径添加到全局$PATH中,它可以在/etc/paths.d/目录下创建一个独立的文件,这样具有更高的可维护性,当需要安装、卸载一个软件相关的路径时,系统只需要创建、删除一个单独的文件,整个路径配置也更加清晰易懂。

用户级别

  1. ~/.bash_profile~/.bash_login~/.profile
    • zsh 下不生效,如果想让其生效,可以修改 ~/.zshrc,在其中添加如:source ~/.bash_profile
    • 语法格式:采用 Shell 命令语法
    • 加载时间:用户登录时加载,根据存在的文件依次执行,优先级为 ~/.bash_profile > ~/.bash_login > ~/.profile
    • 加载原理:在用户登录时按顺序查找,按照从前往后的顺序读取,找到第一个存在的文件并执行其中的命令(后面的几个文件就会被忽略了)
      是否建议修改:建议在这些文件中进行个性化的环境设置,因为它们只对当前用户有效。
    • 建议在这个文件中设置用户级别的自定义配置,它只影响当前用户的非登录 shell 环境

注意:与 Bash 不同,Zsh 并没有类似于 Bash 中的 ~/.bash_profile 配置文件。在 Zsh 中,登录时的配置任务主要集中在 ~/.zprofile 文件中。(还有 .zlogin .zshenv 但是我本机中并没有这些文件)
macOS 环境变量加载探究_第1张图片
2. ~/.bashrc~/.zshrc

  • 只在非登录 shell 中读取。它通常用于配置终端的行为和设置用户自定义的环境变量。
  • 语法格式:采用 Shell 命令语法
  • 加载时间:非登录shell,打开终端窗口时加载。
  • 加载原理:~/.bashrc 文件通常由 Bash 非登录 shell 在启动时加载。它适用于用户的自定义配置,只影响当前终端会话。
  • 建议在这个文件中设置用户级别的自定义配置,它只影响当前用户的非登录 shell 环境。

登录 shell 与非登录 shell

登录 shell :在用户登录系统时启动的交互式 shell。当用户通过终端、SSH 或其他方式登录到系统时,登录 shell 会执行用户的登录配置文件,例如 .bash_profile 等(这些文件根据所使用的 shell 类型可能有所不同),登录配置文件通常包含用于设置环境变量、执行启动脚本以及其他需要在登录时进行的操作。

非登录 shell :在已经登录系统的情况下启动的交互式 shell。当用户在登录后打开新的终端窗口或者运行一个 shell 脚本时,会启动一个非登录 shell。非登录 shell 不会读取用户的登录配置文件(所以,修改 ~/.bash_login 后需要 source xx 才能生效),而是读取 ~/.bashrc~/.zshrc等。这些文件通常包含设置别名、定义函数、配置 shell 提示符等。

在使用Windows系统时不会困惑,因为Windows时典型的单用户操作系统,同时只允许一个用户登录,但是在使用macOS后,会比较困惑,到底什么算用户登录?我在图形化界面输入密码后按回车?还是每打开一个终端?困惑的原因也是每次打开终端,都会有类似 login 的字眼。

在这里插入图片描述
通过几个例子来明确“用户登录”的概念,什么算“用户登录”,什么算“已经登录”

  1. 通过命令行登录一个无图形化界面的Linux操作系统:登录 shell,没什么疑问。
  2. 通过 SSH 远程连接云服务器:登录 shell。通过 SSH 远程登录到服务器时,会启动登录 shell,并执行你的登录配置文件,以确保你获得正确的环境和配置。
  3. 先通过 SSH 远程连接一次云服务器,同时连接第二次:每个 SSH 连接都会启动一个新的登录 shell,即使你在同一用户下打开多个 SSH 连接,它们也是独立的登录 shell。
  4. 通过用户登录界面登录图形化界面 Linux 系统:登录 shell,本质上与1相同。
  5. 通过用户登录界面登录图形化界面 Linux 系统后,再打开一个终端窗口:非登录 shell,不会再次执行登录配置文件,所以为了~/.bash_login中的配置能够做到重启终端生效,我们会在 .bashrc.zshrc 中配置 source ~/.bash_profile
  6. 使用 su 命令切换用户:非登录 shell,不会执行目标用户的登录配置文件。
  7. 执行 shell 脚本:非登录 shell,没什么疑问。

环境变量加载顺序

Mac系统的环境变量,加载顺序为:【这里仅就常见的几种方式做顺序展示,中间过程可能会有一些遗漏】
bash:/etc/profile -> /etc/paths -> /etc/paths.d/ 文件夹所有内容 -> ~/.bash_profile -> ~/.bash_login -> ~/.profile -> ~/.bashrc
zsh:/etc/profile -> /etc/paths -> /etc/paths.d/ 文件夹所有内容 -> ~/.zprofile -> ~/.zshrc

参考资料

  • Mac中环境变量加载顺序 - 宋建明 - 博客园 (cnblogs.com)

  • osx - Use /etc/paths or /etc/paths.d to add items to the PATH in macOS Sierra? - Unix & Linux Stack Exchange

你可能感兴趣的:(macos,macos,环境变量加载顺序)