
当你在终端里定义了一个「别名」,可能一开始用得还挺顺手,但新开一个标签页、重开一次 Terminal,它却失效了……这是因为在命令提示符下输入的 Shell 设置,其生命周期就只限于当前的终端会话。
要想让这些设置永久生效,就必须把它们通通都写入到 Bash 每次启动新会话时,都必需要读取的配置文件中。在大多数 Linux 系统上,这个文件就是 ~/.bashrc。
接下来,我们就一起来梳理.bashrc的存放位置、读取时机和常见配置项,以及如何让所有修改立即生效。
.bashrc 的作用
.bashrc是 Bash 的「用户级」启动脚本,并不是全局的 Linux 配置文件。Bash 在加载它时,所有命令都会在当前 Shell 中执行。因此,别名、函数、提示符设置和 Shell 选项都会直接融入当前会话,不需要额外的导入步骤。
其他 Shell 也有专属的配置文件,比如 zsh 使用的~/.zshrc。
文件名中的rc后缀来自 RUNCOM,这是一款早期的 CTSS 程序,用于执行存储在文件中的命令。这个命名习惯在 Unix 配置文件中一直被保留至今,类似名称的配置文件还有.vimrc、.screenrc和.inputrc等。
.bashrc 存放位置
.bashrc默认存放在用户的 Home 目录中。开头的小数点说明它是一个隐藏文件,你没法使用ls直接看到它,需要加上-a参数:
ls -la ~/.bashrc

在 Linux 上,每个用户账户都有自己独立的.bashrc副本(专人专用),修改你自己的文件并不会影响到系统中的其他用户。而且该文件是纯文本格式,任何文本编辑器比如 vim 和 nano 都能直接编辑:
nano ~/.bashrc
即便该文件不存在,系统也不会报错,Bash 会直接跳过它。有不少 Linux 发行版会在/etc/skel/目录下提供一个模板,在创建新用户时,就自动把它复制到用户的 Home 目录。所以,你可以通过以下命令来恢复默认配置:
cp /etc/skel/.bashrc ~/.bashrc
当然了,你也可以从零开始,直接创建一个空文件。
Bash 在什么时候会读取 .bashrc
当 Bash 启动一个「交互式非登录 Shell」时,它就会自行读取~/.bashrc。说人话就是:当你在桌面环境中打开一个新的终端窗口或标签页,或者在当前 Shell 中直接输入bash开启子 Shell 时,系统就会加载该文件。
但有 2 种常见情况并不符合以上条件:
- 登录 Shell:通过 SSH 远程登录或在控制台登录系统时,启动的是登录 Shell。这个时候,Bash 会先读取
/etc/profile,然后在~/.bash_profile、~/.bash_login和~/.profile中按顺序寻找并读取第一个可读文件。 - 非交互式 Shell:运行本地脚本启动的是非交互式 Shell,通常也不会读取上述任何文件。但如果你设置了
BASH_ENV环境变量,Bash 会在运行脚本之前,读取该变量所指定的文件。
为了让交互式设置在登录和非登录 Shell 中都能生效,最常见的做法就是把配置统一写到~/.bashrc中,并在登录 Shell 的配置文件(如~/.bash_profile)中,通过代码来引入它。
文件顶部的「交互性检查代码」
如果你在 Debian 或 Ubuntu 中打开默认的 ~/.bashrc,在开头应该会看到有这样一段代码:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
变量$-保存着当前 Shell 的标志位。只有在交互式 Shell 中,它才会包含字母i。如果缺少i,return命令就会直接终止后续的读取动作。

之所以会存在这道「安全门」,是因为 Bash 的一个特殊机制:
- 当 Bash 探测到标准输入被连接到网络(比如执行类似
ssh user@host 'command'的远程命令)时,即便当前 Shell 是非交互式的,它也会强制读取~/.bashrc。 - 如果没有这段检查代码,当你在执行远程命令或文件传输时触发了服务器端的 Bash,
.bashrc里面的所有配置就都会被盲目执行一遍。
请保留这段检查代码,并将所有交互式设置写在它的下面。除非某个非交互式远程命令确实需要特定的环境变量,否则写在检查代码上方的任何内容都必须保持静默(不产生输出)。
应该在 .bashrc 里面写些什么
任何影响交互式 Shell 行为的配置都适合放在里面。以下是最常见的几类配置:
别名定义
别名(Alias)可以为冗长的命令创建更简短的替代名称,比如
alias ll='ls -alF'
alias gs='git status'
alias ..='cd ..'
自定义函数
如果一个快捷操作需要传入参数,或者包含多条命令组合,可以使用函数来代替别名:
mkcd () {
mkdir -p "$1" && cd "$1"
}
这样一来,你只要执行mkcd projects/api,系统就会自动创建该目录并跳转进去。
交互式环境变量 $PATH 补充
为了让 Bash 能在交互式提示符下直接运行你自定义目录中的可执行文件,需要将该目录追加到$PATH环境变量中:
export PATH="$HOME/.local/bin:$PATH"
- 把
$PATH放在末尾,可以保留系统原有的目录层级。如果你把自定义目录放在最前面,在出现同名命令时,系统就会优先执行你的自定义版本。 - 这项修改只对读取
.bashrc的 Shell 生效。如果想让 GUI 程序或其他 Shell 也能识别该路径,可以把配置写到~/.profile或~/.bash_profile当中。
普通环境变量
你还可以在这里配置「由交互式 Bash 启动的程序」所依赖的环境变量。使用export导出变量,确保子进程能继承这些值:
export EDITOR=nano
export LESS='-R'
- 如果某些变量需要跨整个登录会话存在(包括那些并非由终端启动的应用程序),请改用登录配置文件或桌面环境的专属配置文件。
- 切勿将 API 密钥、Token 或密码直接硬编码进
.bashrc中。请将机密信息存放在独立的、版本控制系统会忽略的文件里,权限设置为chmod 600,或者直接使用专门的凭据管理器。
Shell 提示符
PS1变量用于定义命令行提示符的格式。以下示例会利用颜色来显示用户名、主机名和当前目录:
PS1='\[\e[32m\]\u@\h\[\e[0m\]:\[\e[34m\]\w\[\e[0m\]\$ '
\[和\]标记用来告诉 Bash,它们包围的转义序列不占用屏幕宽度。如果漏掉这些标记,当你在输入长命令时,终端里的文本换行将会出现错乱。
Shell 选项
shopt命令用于开启或关闭一些(默认禁用)的 Bash 特性:
shopt -s autocd # 输入要进入的目录名
shopt -s cdspell # 修正 cd 参数中的拼写错误
shopt -s globstar # ** 跨子目录匹配文件
shopt -s histappend # 追加到历史记录文件而不是覆盖
像HISTSIZE和HISTCONTROL这样的历史记录配置,一般也存放在这个文件中。
立即应用更改
由于 Bash 只会在启动时读取~/.bashrc,所以文件修改之后,当前正在运行的 Shell 并不会受到影响。
1在重新加载配置之前,建议先检查一下语法有没有错误:
bash -n ~/.bashrc
2如果没有输出,说明 Bash 没有发现问题。接着:
- 直接引入该文件即可立即生效:
source ~/.bashrc
- 在 Bash 中,
.就是source的 POSIX 标准简写形式,以下命令的作用完全相同:
. ~/.bashrc

上述命令会在当前 Shell 环境中执行该文件,新添加的别名、函数和变量都会立刻生效。但需要注意的是,source动作并不会「撤销」配置。如果你在文件中删除了某个别名,再重新加载时,它还是存在于当前会话中,除非你执行unalias移除它,或者新开一个终端窗口。
把 .bashrc 拆分成独立文件
如果你的.bashrc代码量膨胀到数百行,拆分成多个独立文件会更方便维护。Debian 和 Ubuntu 的默认配置就已经对「别名」采用了这种处理方式:
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
1为了实现更通用的拆分方案,你可以新建一个目录来存放附加脚本:
mkdir -p ~/.bashrc.d
2然后在~/.bashrc中添加一段循环逻辑,用来引入该目录下所有可读的 Shell 文件:
if [ -d ~/.bashrc.d ]; then
for rc in ~/.bashrc.d/*.sh; do
[ -r "$rc" ] && . "$rc"
done
unset rc
fi
Bash 会按照字母顺序依次引入文件。比如,10-path.sh会比20-aliases.sh要先执行。这种结构方便你把工作专用的配置剥离出来,按需放置或移除,而无需反复修改.bashrc本体。
bash -n ~/.bashrc并不会检查被引入的外部文件,每次修改后需要你对这些子文件单独执行语法检查。
Fedora 和 RHEL 默认已经配置了读取~/.bashrc.d/目录,所以在增加这部分循环代码之前,请先检查现有配置是否已经包含该功能。
不要写入 .bashrc 的内容
我们最需要避开的是,那些会向终端「打印输出」的命令:
- 如果你在「交互性检查代码」上方放置了类似
neofetch或echo "Welcome back"这样的命令,虽然在普通终端里看起来无伤大雅,但它们却会在scp、rsync和ssh host 'command'建立会话时被执行。这部分多余的文本输出会直接破坏网络协议流,导致传输工具执行失败。
请务必将所有要「打印内容」的命令放到「交互性检查逻辑」之下,或直接将登录问候语移到登录配置文件中。
- 另外,
.bashrc里的所有内容都会在命令行提示符出现之前执行完毕,应该避免在其中放置耗时较长的命令。比如,发起网络请求或初始化版本管理器需要耗费半秒钟,那么你每次打开新终端时,都会感受到这半秒种延迟的「深深恶意😂」。
快速参考表
| 配置项 | 示例 | 作用说明 |
|---|---|---|
| 别名 | alias ll='ls -alF' | 为冗长命令设定简短名称 |
| 函数 | mkcd () { mkdir -p "$1" && cd "$1"; } | 支持传入参数的快捷操作 |
| 交互式 PATH 补充 | export PATH="$HOME/.local/bin:$PATH" | 将可执行文件目录加入交互式 Bash |
| 环境变量 | export EDITOR=nano | 由 Bash 启动的程序所继承的设置 |
| 提示符 | PS1='\u@\h:\w\$ ' | 设置 Shell 提示符格式 |
| Shell 选项 | shopt -s autocd | 开启或关闭某项 Bash 特性 |
| 引入文件 | . ~/.bash_aliases | 从外部文件加载配置 |
| 语法检查 | bash -n ~/.bashrc | 在不运行的前提下检查文件语法 |
| 重新加载 | source ~/.bashrc | 将修改应用到当前 Shell |













猪年快乐~
狗年快乐~