《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 读取用户登录文件时,按顺序三选一:
    1. ~/.bash_profile
    2. ~/.bash_login
    3. ~/.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:都在子进程执行,不影响当前终端,也不影响其他终端。
  • 已经打开的其他终端不会自动更新。
  • 想让所有终端生效:
    1. 修改配置文件,如 ~/.bashrc、~/.profile、/etc/profile.d/*.sh
    2. 每个终端自己 source,或重新打开终端/重新登录

posted @ 2026-10-28 16:47  哪能咋办嘛  阅读(11)  评论(0)    收藏  举报