《Bash配置文件与脚本执行方式速查:bashrc、bash_profile、profile 及 source、bash、sh、./ 的区别》
Shell 配置文件与执行方式速查
1. 三个用户级配置文件分别放什么
| 文件 | 典型存放内容 | 加载时机 | 关键说明 |
|---|---|---|---|
~/.bashrc |
alias、Shell 函数、PS1 提示符、补全、Shell 选项、交互式环境变量 |
每次打开交互式非登录 Shell(如新开终端) | 登录 Shell 默认不读它,通常由 ~/.bash_profile 或 ~/.profile 显式 source |
~/.bash_profile |
登录 Shell 的环境变量(如 PATH)、登录时启动程序、source ~/.bashrc |
登录 Shell 读取;优先级最高 | 如果它存在,Bash 不再读 ~/.bash_login 和 ~/.profile |
~/.profile |
兼容 sh / 桌面登录的环境变量、PATH、登录启动项 |
当 ~/.bash_profile 和 ~/.bash_login 都不存在时,登录 Shell 读取 |
Ubuntu/Debian 默认常见;可被显示管理器或其他 Shell 读取 |
三者关系
- 登录 Bash 读取用户登录文件时,按顺序三选一:
~/.bash_profile~/.bash_login~/.profile
- 读到第一个存在的就停止,不会三个都读。
- 交互式非登录 Bash 主要读
~/.bashrc。 - 常见做法是在
~/.bash_profile里加:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
这样登录 Shell 也能用上 ~/.bashrc 里的别名和函数。
放置建议
- 环境变量:放
~/.profile或~/.bash_profile - 别名、函数、提示符:放
~/.bashrc - 系统级环境变量:放
/etc/profile.d/*.sh - 不要直接改
/etc/environment来 source,它不是 Shell 脚本
2. source、bash、sh、./ 的区别
| 方式 | 谁在执行 | 是否启动子进程 | 需要 x 权限 |
是否看 shebang | 执行内容 | 对当前 Shell 影响 | 适用对象 |
|---|---|---|---|---|---|---|---|
source file 或 . file |
当前 Shell 读取并执行 | 否 | 不需要,只需可读 | 不看 | 文件中的 Shell 命令 | 直接影响当前 Shell:变量、函数、cd、别名、exit 都会生效 |
加载配置、让变量/函数立即生效 |
bash file |
启动一个 Bash 子进程解释执行 | 是 | 不需要,只需可读 | 不看,shebang 当注释 | 文件内容按 Bash 语法执行 | 不影响当前 Shell | Bash 脚本 |
sh file |
启动一个 sh 子进程解释执行 |
是 | 不需要,只需可读 | 不看 | 文件内容按 sh 语法执行 |
不影响当前 Shell | POSIX shell 脚本 |
./file |
内核 execve 按文件本身执行 |
是 | 需要 | 看 | shebang 指定的解释器执行脚本,或 ELF 二进制直接运行 | 不影响当前 Shell | 正常脚本、二进制程序 |
一句话理解
source file:当前 Shell 里执行文件内容,不 fork。bash file:开一个 Bash 子进程执行文件内容。sh file:开一个 sh 子进程执行文件内容。./file:让内核按文件本身执行,看 shebang 或 ELF。
注意
./不是解释器,只是“当前目录”的路径前缀。bash ./file和bash file基本等价。sh在 Ubuntu/Debian 上通常是dash,不是 Bash;Bash 特有语法如[[ ]]、数组、function、source可能失败。- 二进制程序不能
bash program、sh program、source program,只能./program或绝对路径执行。 source是 Bash 内建;POSIX Shell 用. file。./file如果没有 shebang,行为不可靠,不要依赖。- shebang 必须在第一行,例如
#!/usr/bin/env bash。
3. 用一个脚本看差异
文件 a.sh:
#!/usr/bin/env bash
echo "0=$0"
export FOO=bar
cd /tmp
对比:
| 执行方式 | $0 通常是 |
FOO 是否留在当前 Shell |
当前目录是否变成 /tmp |
是否影响当前终端 |
|---|---|---|---|---|
./a.sh |
./a.sh |
否 | 否 | 否 |
bash a.sh |
a.sh |
否 | 否 | 否 |
sh a.sh |
a.sh |
否 | 否 | 否 |
source a.sh |
当前 Shell 的 $0 |
是 | 是 | 是,仅当前终端 |
补充:
bash a.sh里exit 1只退出子进程,父 Shell 还在。source a.sh里exit 1会退出当前 Shell。source不要求可执行权限,也不看 shebang。./a.sh需要chmod +x a.sh。
4. 配置文件何时被自动读取
登录 Shell
例如 SSH 登录、su -、部分系统的新终端:
/etc/profile
-> /etc/profile.d/*.sh
-> ~/.bash_profile 或 ~/.bash_login 或 ~/.profile(三选一)
-> 如果其中 source 了 ~/.bashrc,则再读 ~/.bashrc
交互式非登录 Shell
例如图形界面里新开终端:
/etc/bash.bashrc(Ubuntu/Debian)或 /etc/bashrc(RHEL/CentOS)
-> ~/.bashrc
非交互式 Shell
例如 bash script.sh:
- 通常不读上述配置文件。
- 可能读取
$BASH_ENV指向的文件。 cron任务不会自动读~/.bashrc或~/.profile。
5. 跨终端问题
source ~/.bashrc:只影响当前终端。bash script、sh script、./script:都在子进程执行,不影响当前终端,也不影响其他终端。- 已经打开的其他终端不会自动更新。
- 想让所有终端生效:
- 修改配置文件,如
~/.bashrc、~/.profile、/etc/profile.d/*.sh - 每个终端自己
source,或重新打开终端/重新登录
- 修改配置文件,如
浙公网安备 33010602011771号