在 Shell 脚本中,sh 和 source(或 .)是两种不同的执行脚本的方式,它们的行为和效果有显著区别。以下是它们的详细对比:
1. sh 命令
sh 是一个独立的 Shell 进程,用于执行指定的脚本文件或命令。
特点:
- 启动子 Shell:
sh会启动一个新的子 Shell 进程来执行脚本。 - 隔离环境:子 Shell 中的变量、函数和别名等不会影响父 Shell。
- 脚本执行完毕后退出:子 Shell 执行完脚本后会退出,所有在子 Shell 中定义的内容都会丢失。
示例:
# script.sh
#!/bin/bash
export VAR="Hello, World!"
echo $VAR
执行:
sh script.sh
- 输出:
Hello, World! - 但在父 Shell 中,
VAR变量不存在:
echo $VAR # 输出为空
2. source 命令
source(或 .)用于在当前 Shell 环境中执行脚本。
特点:
- 不启动子 Shell:脚本在当前 Shell 中执行。
- 共享环境:脚本中定义的变量、函数和别名等会影响当前 Shell。
- 常用于加载配置文件:例如
~/.bashrc或~/.zshrc。
示例:
# script.sh
#!/bin/bash
export VAR="Hello, World!"
echo $VAR
执行:
source script.sh
- 输出:
Hello, World! - 在父 Shell 中,
VAR变量仍然存在:
echo $VAR # 输出:Hello, World!
3. sh 和 source 的区别对比
| 特性 | sh | source |
|---|---|---|
| 执行环境 | 启动子 Shell | 在当前 Shell 中执行 |
| 变量作用域 | 子 Shell 中的变量不影响父 Shell | 脚本中的变量会影响当前 Shell |
| 函数和别名 | 子 Shell 中定义的函数和别名不会保留 | 脚本中定义的函数和别名会保留 |
| 典型用途 | 执行独立脚本 | 加载配置文件或环境变量 |
| 命令格式 | sh script.sh | source script.sh 或 . script.sh |
4. 实际应用场景
使用 sh 的场景
- 执行独立的脚本,不需要影响当前 Shell 环境。
- 运行一次性任务,例如测试脚本。
使用 source 的场景
- 加载配置文件,例如
~/.bashrc或~/.zshrc。 - 设置环境变量或函数,使其在当前 Shell 中生效。
5. 示例对比
示例 1:定义变量
# script.sh
export VAR="Hello, World!"
- 使用
sh:
sh script.sh
echo $VAR # 输出为空,因为 VAR 在子 Shell 中定义
- 使用
source:
source script.sh
echo $VAR # 输出:Hello, World!
示例 2:定义函数
# script.sh
myfunc() {
echo "This is a function"
}
- 使用
sh:
sh script.sh
myfunc # 报错:myfunc 未定义
- 使用
source:
source script.sh
myfunc # 输出:This is a function
6. 注意事项
source和.是等价的:在大多数 Shell 中,source script.sh和. script.sh是完全相同的。- 脚本权限:使用
sh执行脚本时,脚本需要具有可执行权限;而使用source时,脚本不需要可执行权限。 - 脚本中的
exit:如果脚本中包含exit,使用source会导致当前 Shell 退出,而使用sh只会退出子 Shell。
总结
- 使用
sh执行脚本时,脚本在子 Shell 中运行,不会影响当前 Shell 环境。 - 使用
source执行脚本时,脚本在当前 Shell 中运行,会影响当前 Shell 环境。 - 根据需求选择合适的方式:如果需要脚本中的变量或函数在当前 Shell 中生效,使用
source;如果希望脚本独立运行,使用sh。