一文理清 Mac/Linux 终端配置文件(.bash_profile, .bashrc, .zshrc)

在配置开发环境时,我们经常会被各种教程指导去修改 ~/.bash_profile~/.bashrc 或者 ~/.zshrc

"把环境变量加进去,然后 source 一下。"

照做虽然能跑,但很多人对这几个文件到底有什么区别、到底该写在哪个文件里,往往是一头雾水。今天,我们就来把它们的关系明明白白地梳理清楚。

核心前提:你用的是什么 Shell?

在搞清楚文件之前,首先要弄清楚你当前的"壳(Shell)"是什么。终端只是一扇门,Shell 才是真正在背后干活的人。

  • Bash:老牌经典,曾经是 macOS 和大多数 Linux 系统的默认 Shell。
  • Zsh:后起之秀,功能更强大。从 macOS Catalina (10.15) 开始,苹果将默认 Shell 换成了 Zsh。

你可以通过在终端输入 echo $SHELL 来查看你当前使用的是哪一个。

  • 输出 /bin/bash -> 你在用 Bash
  • 输出 /bin/zsh -> 你在用 Zsh

场景一:如果你在使用 Bash

对于 Bash 用户,理解配置文件的关键在于理解两种登录模式。你可以把终端想象成一个工作间。

1. 登录 Shell (Login Shell) ------ "早间打卡清单"

  • 什么时候发生 :当你通过 SSH 远程连接到服务器,或者在 Mac 上新打开一个终端窗口时。
  • 读取哪个文件 :系统会去找 ~/.bash_profile (如果找不到,会依次找 ~/.bash_login~/.profile)。
  • 里面该放什么 :通常放环境变量 (比如 export PATH=...、NVM 的初始化脚本)。因为环境变量会继承给子进程,所以"早上打卡"时设置一次就够了。

⚠️ Mac 的特殊性 :在 Linux 系统中,打开图形界面的终端通常属于"非登录",但在 Mac 中,苹果规定每次打开新终端窗口,都算是"登录",所以 Mac 会强行去读 ~/.bash_profile

2. 非登录 Shell (Non-login Shell) ------ "会议室清单"

  • 什么时候发生 :当你在已经打开的终端里,输入 bash 命令进入一个子终端,或者运行一个 Bash 脚本时(相当于你已经在公司了,只是从工位去了一趟会议室)。
  • 读取哪个文件 :它只找 ~/.bashrc
  • 里面该放什么 :通常放一些"命令别名"(比如 alias ll='ls -l')或者自定义函数。因为这些东西不会继承,所以每次开"会议室"都得重新定义一遍。

💡 最佳实践 (Best Practice)

为了防止在切换环境时丢失配置,业界标准的做法是: 把所有的配置(环境变量、别名等)都写进 ~/.bashrc 中,然后在 ~/.bash_profile 里加上下面这段代码去调用它:

bash 复制代码
if [ -f ~/.bashrc ]; then
    source ~/.bashrc
fi

这样,无论你是怎么进入 Bash 的,配置都能完美生效。

场景二:如果你在使用 Zsh

如果你使用的是 Zsh(现在大多数 Mac 用户的状态),事情就简单多了。

  • 读取哪个文件 :无论你是登录还是非登录,打开新窗口还是开子终端,Zsh 都会去读取 ~/.zshrc
  • 里面该放什么 :随便放!不管是环境变量、别名,还是 NVM、Homebrew 的初始化脚本,一股脑全写进 ~/.zshrc 里就行了。

这也是为什么现在很多新的教程,都直接让你修改 ~/.zshrc 的原因。

为什么修改完还要 source 一下?

因为终端只在"启动"的那一瞬间去读取这些配置文件。 如果你中途修改了文件(比如加了新的环境变量),当前正在运行的终端是不知道的。

source ~/.bash_profilesource ~/.zshrc 的作用,就是告诉当前终端:"别等下次重启了,现在立刻马上把配置重新读一遍!"

总结

  • 用 Bash :重点维护 ~/.bash_profile~/.bashrc。Mac 每次开窗口读 _profile
  • 用 Zsh :死磕 ~/.zshrc 就完事了。
  • 改完没生效 :记得 source 一下,或者关掉终端重新开一个。

理清了这些,下次再遇到"command not found",你就知道该去哪个文件里找问题啦!

相关推荐
Rust研习社2 小时前
Rust 性能陷阱:那些看起来很优雅但很慢的写法(上)
后端·rust·编程语言
万亿少女的梦1682 小时前
基于SpringBoot的在线考试管理系统设计与实现
java·spring boot·后端
DianSan_ERP2 小时前
京东订单接口集成中如何处理消费者敏感信息的安全与合规问题?
前端·数据库·后端·团队开发·运维开发
web守墓人2 小时前
【go语言】go语言实现go-torch, 完成Lenet-5的搭建,训练,以及pth和onnx模型导出
开发语言·后端·golang
平凡但不平庸的码农2 小时前
Go 语言常用标准库详解
开发语言·后端·golang
码云数智-园园3 小时前
Spring循环依赖:三级缓存到底解决了什么,没解决什么?
java·后端·spring
Shadow(⊙o⊙)3 小时前
初识Qt+经典方式实现hello world!的交互
开发语言·c++·后端·qt·学习
Neobee3 小时前
国内用 Terraform 管 Cloudflare 踩过的 5 个坑(附可直接复用的代码)
后端
平凡但不平庸的码农3 小时前
Go context 包详解
开发语言·后端·golang