source 是什么?
source 是一个 Shell 内置命令,它的主要作用是在当前 Shell 环境中执行一个脚本文件,而不是创建一个新的子 Shell 来执行。

为了更好地理解,我们需要区分两种执行脚本的方式:
- 直接执行脚本(
./script.sh或/path/to/script.sh) - 使用
source执行脚本(source script.sh)
两种执行方式的根本区别
这是理解 source 的关键,我们用一个表格来对比:
| 特性 | 直接执行 (./script.sh) |
使用 source 执行 (source script.sh) |
|---|---|---|
| Shell 环境 | 创建一个新的子 Shell,脚本在这个子 Shell 中运行。 | 在当前 Shell 中运行,不创建新的子 Shell。 |
| 变量影响 | 脚本内部定义的变量、函数等,生命周期仅限于子 Shell,当脚本执行完毕,回到父 Shell 后,这些变量会自动消失,不会影响父 Shell 的环境。 | 脚本内部定义的变量、函数等,会直接添加到当前 Shell 的环境中,脚本执行完毕后,这些变量和函数仍然存在,可以被后续的命令使用。 |
| 脚本权限 | 脚本文件必须有执行权限 (chmod +x script.sh)。 |
脚本文件不需要执行权限,只要有读取权限即可。 |
| 常用别名 | bash script.sh 或 sh script.sh(效果类似,但可能不完全等同于 ) |
(点号) |
一个生动的比喻
想象一下你正在一个大办公室(当前 Shell)里工作。
-
直接执行 (
./script.sh): 你叫来一个实习生(子 Shell),让他去执行一个任务(运行脚本),实习生在自己的工位上(子 Shell 环境)工作,他创建了一些临时文件和笔记(变量),任务完成后,实习生离开了(子 Shell 销毁),你自己的工位(当前 Shell 环境)上什么都没多,一切都和之前一样。
(图片来源网络,侵删) -
使用
source执行 (source script.sh): 你没有叫来实习生,而是亲自去执行这个任务,你在自己的工位上工作,你把任务需要的工具(变量)和操作手册(函数)都放到了自己桌上,任务完成后,这些工具和手册依然留在你的桌上,你可以继续使用它们。
source 的实际应用场景
理解了上面的区别,source 的用途就非常清晰了。
加载环境变量配置文件
这是 source 最常见的用途,很多软件(尤其是基于 Python 的虚拟环境、Node.js 的 nvm 等)会提供一个 activate 或类似的脚本来设置环境变量。
示例:

假设你有一个 my_config.env 文件,内容如下:
# my_config.env export MY_DATABASE_URL="postgresql://user:pass@host:port/db" export API_KEY="abcdef123456"
如果你直接运行 ./my_config.env,这些环境变量只会在子 Shell 中设置,没有意义。
正确的方式是使用 source:
source my_config.env
执行后,你可以在当前的 Shell 中直接使用这些变量:
echo $MY_DATABASE_URL # 输出: postgresql://user:pass@host:port/db echo $API_KEY # 输出: abcdef123456
加载 Shell 函数库
你可以将常用的函数定义在一个文件中,然后在主脚本或交互式 Shell 中 source 它,从而复用这些函数。
示例:
创建一个 functions.sh 文件:
# functions.sh
function greet() {
echo "Hello, $1! Welcome to our system."
}
function get_current_time() {
date +"%Y-%m-%d %H:%M:%S"
}
在你的主脚本 main.sh 中:
#!/bin/bash # main.sh # 加载函数库 source ./functions.sh # 现在可以直接使用 functions.sh 中定义的函数了 greet "Alice" echo "The current time is: $(get_current_time)"
运行 ./main.sh,输出将是:
Hello, Alice! Welcome to our system.
The current time is: 2025-10-27 15:30:00
在交互式 Shell 中临时修改配置
你想临时修改 PATH 变量或者设置一些别名,你可以写一个脚本 setup_dev_env.sh,source 它,这样,这些修改只对当前会话有效,关闭终端后自动恢复,非常方便。
source 的别名: (点号)
在 Shell 中, (点号) 是 source 的一个完全等价的别名,它们的功能和行为完全相同。
# 这两行命令的效果完全一样 source my_config.env . my_config.env
使用 是一个非常普遍和简洁的做法,尤其是在 Linux 和 macOS 的系统初始化脚本中(/etc/profile 会 source /etc/profile.d/ 下的脚本)。
| 命令 | 别名 | 行为 | 主要用途 |
|---|---|---|---|
source script.sh |
script.sh | 在当前 Shell中执行脚本 | 加载环境变量、函数库,修改当前 Shell 的环境 |
bash script.sh |
(无) | 在子 Shell中执行脚本 | 独立运行一个脚本,不影响当前环境 |
当你希望一个脚本能永久性地改变你当前 Shell 的状态(比如设置变量、定义函数)时,就使用 source 或 ,当你只是想运行一个脚本,然后把它和它的环境一起丢弃时,就直接用 bash 或 。
