source 命令是什么?
source 是一个 Shell 内置命令,它的作用是在当前 Shell 环境中执行指定的文件。

一个非常重要的核心概念:
source 命令执行脚本文件时,不会创建一个新的子 Shell 进程,而是直接在当前的 Shell 进程中运行脚本中的所有命令,这意味着,脚本中设置的任何变量、函数、别名或环境变量的更改,都会直接、永久地影响到当前的 Shell 会话。
这与直接执行脚本(./script.sh)形成了鲜明对比,直接执行脚本时,系统会创建一个新的子 Shell 来运行它,脚本执行完毕后,这个子 Shell 会被销毁,所有在子 Shell 中产生的变更(如变量赋值)也会随之消失,不会影响到父 Shell。
source 命令的语法
source filename [arguments]
或者使用它的简写形式(一个点 ):

. filename [arguments]
这两种写法在功能上是完全等价的。 是 POSIX 标准中规定的写法,因此在所有兼容的 Shell(如 sh, bash, zsh)中都有效。source 是 Bash 中的一个同义词,可读性更好,推荐使用。
source 命令最常见的用途
在 CentOS 系统中,source 命令最广泛、最重要的用途就是加载 Shell 配置文件。
临时使配置文件生效
当你手动修改了某个 Shell 配置文件(如 ~/.bashrc, ~/.bash_profile)后,这些修改不会立即对当前的 Shell 会话生效,你需要注销并重新登录,或者使用 source 命令来让配置立即加载。
场景示例:

假设你刚刚在 ~/.bashrc 文件末尾添加了一个新的别名:
# 在 ~/.bashrc 文件中添加 alias ll='ls -alF'
你希望在不关闭当前终端窗口的情况下,让这个 ll 别名立即可用,你可以这样做:
# 方法一:使用 source 命令(推荐) source ~/.bashrc # 方法二:使用 . (点) 命令 . ~/.bashrc
执行后,你就可以在当前终端中直接使用 ll 命令了,如果不使用 source,你需要关闭终端再重新打开一个新的,或者注销后重新登录。
切换用户环境
在系统管理中,经常需要从 root 用户切换到普通用户,或者反之,切换后,新用户的环境变量(如 PATH)可能还没有正确加载。
场景示例:
你以 root 用户登录,现在需要切换到 tom 用户来执行一些操作。
# 切换到 tom 用户 su - tom # tom 用户的环境变量(如 .bash_profile)可能还未完全加载 # 你可以手动 source 一下 source ~/.bash_profile # 或者对于 CentOS/RHEL,通常是 source ~/.bashrc
注意: su - username 和 su username 的区别:
su - username:会模拟一个完整的登录过程,会加载目标用户的全局配置文件(如/etc/profile)和用户配置文件(如~/.bash_profile),环境变量是全新的。su username:只是切换用户身份,但仍然在当前的 Shell 环境中,不重新加载配置文件,如果你是从一个非登录 Shell 切换的,source命令就很有用。
在脚本中加载其他脚本或函数
在编写复杂的 Shell 脚本时,你可能会将一些通用的函数或变量定义放在单独的文件中(functions.sh 或 config.sh),然后在主脚本中加载它们,以提高代码的模块化和复用性。
场景示例:
假设你有一个 functions.sh 文件:
# functions.sh
function greet() {
echo "Hello, $1!"
}
然后你的主脚本 main.sh 需要使用这个 greet 函数:
#!/bin/bash # main.sh # 加载 functions.sh 文件,使其中的函数在当前脚本中可用 source ./functions.sh # 现在可以调用 greet 函数了 greet "World"
运行 main.sh,输出将是:
Hello, World!
source 与 (点号) 的区别总结
这是一个非常容易混淆但又至关重要的知识点,下面用一个表格来清晰地对比:
| 特性 | source script.sh 或 . script.sh |
./script.sh |
|---|---|---|
| 执行环境 | 当前 Shell (Current Shell) | 子 Shell (Sub-shell) |
| 进程创建 | 不创建新的进程 | 创建一个新的子进程来执行脚本 |
| 变量作用域 | 脚本中设置的变量、函数、别名等会永久影响当前 Shell | 脚本中设置的变量、函数、别名等仅在子 Shell 中有效,脚本执行完毕后失效 |
| 适用场景 | 加载配置文件 (如 .bashrc)在脚本中复用其他脚本的函数/变量 让环境变更立即生效 |
执行一个独立的程序或任务 脚本本身是一个完整的工具,不需要修改当前环境 |
| 权限要求 | 脚本文件不需要有执行权限 (x) |
脚本文件必须有执行权限 (x),或者用 bash script.sh 的方式 |
实践示例
让我们通过一个简单的例子来直观感受区别。
创建一个测试脚本 test.sh
# test.sh #!/bin/bash echo "当前脚本的进程 ID (PID) 是: $$" echo "正在设置一个变量 MY_VAR..." MY_VAR="Hello from script" echo "变量 MY_VAR 已设置为: $MY_VAR"
给脚本添加执行权限
chmod +x test.sh
测试 (子 Shell) 方式
$ echo "执行前,MY_VAR 的值是: $MY_VAR" 执行前,MY_VAR 的值是: $ ./test.sh 当前脚本的进程 ID (PID) 是: 12345 正在设置一个变量 MY_VAR... 变量 MY_VAR 已设置为: Hello from script $ echo "执行后,MY_VAR 的值是: $MY_VAR" 执行后,MY_VAR 的值是:
分析:
- 脚本执行时,我们看到它的 PID (12345) 和当前终端的 PID 不同,说明它在一个新的子进程中运行。
- 脚本内部设置了
MY_VAR,但当脚本执行完毕回到终端后,MY_VAR的值依然是空的,说明变量的修改没有传递回父 Shell。
测试 source (当前 Shell) 方式
$ echo "执行前,MY_VAR 的值是: $MY_VAR" 执行前,MY_VAR 的值是: $ source test.sh 当前脚本的进程 ID (PID) 是: 12346 # 注意,这里的 PID 和当前终端的 PID 是相同的! 正在设置一个变量 MY_VAR... 变量 MY_VAR 已设置为: Hello from script $ echo "执行后,MY_VAR 的值是: $MY_VAR" 执行后,MY_VAR 的值是: Hello from script
分析:
- 脚本执行时,它的 PID (12346) 和当前终端的 PID 完全一样,说明它就在当前 Shell 中运行。
- 脚本执行完毕后,
MY_VAR的值被成功保留下来,说明变量的修改永久地影响了当前的 Shell 环境。
在 CentOS 系统管理中,source 命令是一个简单但功能强大的工具,理解它与子 Shell 执行的本质区别,对于高效地管理环境变量、配置文件和编写模块化的 Shell 脚本至关重要,记住它的核心用途:让配置文件在当前 Shell 立即生效,以及在脚本间共享代码。
