Shell 脚本中 source 执行与 sh 执行脚本环境变量区别是什么?

文章导读
Shell 脚本中 source 执行会在当前 shell 环境中运行,变量修改直接生效;sh 执行会启动子 shell,变量修改仅在子进程内有效,执行结束后丢失。需要保留环境变量变更时使用 source,运行独立任务时使用 sh。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

Shell 脚本中 source 执行会在当前 shell 环境中运行,变量修改直接生效;sh 执行会启动子 shell,变量修改仅在子进程内有效,执行结束后丢失。需要保留环境变量变更时使用 source,运行独立任务时使用 sh。

先说结论:source 命令在当前 shell 进程执行脚本,能修改当前环境变量;sh 命令新建子进程执行脚本,无法修改当前 shell 环境变量。

  • 适合场景:source 用于加载配置文件或激活虚拟环境,sh 用于运行独立任务脚本。
  • 重点看变量域:source 执行后变量在当前终端可用,sh 执行后变量随子进程销毁。
  • 别忽略权限:source 执行脚本不需要可执行权限,sh 执行通常也不需要但行为不同。

命令速用版

直接复制以下命令测试变量传递效果,确认当前 shell 是否被修改。

echo "export TEST_VAR=source_ok" > test.sh
source test.sh
echo $TEST_VAR
# 输出:source_ok

sh test.sh
echo $TEST_VAR
# 输出:source_ok (因为上面已经设置了,若重置终端再测 sh 则输出为空)

若需严格对比,请先 unset 变量再分别测试。

为什么会这样

根本区别在于执行脚本时是否创建了新的进程。source 是 shell 内建命令,直接在当前 shell 读取并执行文件内容,相当于把脚本代码粘贴到当前终端运行;sh 命令会调用系统 shell 程序启动一个新的子进程,子进程继承父进程环境但修改不回传。

这种机制决定了变量作用域的不同。当前 shell 中定义的局部变量,子 shell 无法直接使用;父 shell 的环境变量子 shell 可以继承,但子 shell 中新建或修改的变量无法影响父 shell。source 绕过进程隔离,直接操作当前内存空间中的变量表。

分步处理

根据脚本目的选择执行方式,避免环境变量污染或失效。

步骤 1:判断脚本用途

如果脚本目的是修改 PATH、设置别名、激活虚拟环境(如 source venv/bin/activate),必须使用 source。如果脚本目的是运行一次性任务、编译代码或后台服务,使用 sh 或 ./script.sh。

步骤 2:检查脚本权限

Shell 脚本中 source 执行与 sh 执行脚本环境变量区别是什么?

source 命令不需要脚本具备可执行权限(x 权限),即使脚本权限为 644 也能执行。sh 命令同样不需要可执行权限,但直接执行 ./script.sh 需要 chmod +x 权限。

步骤 3:执行并确认

执行命令后,立即使用 echo 检查关键变量。若变量未生效且脚本逻辑依赖该变量,说明执行方式错误,需切换为 source。

怎么验证是否生效

通过检查变量值和 shell 层级确认执行环境。

检查变量值

在脚本中设置特定变量,执行后在当前终端 echo 该变量。若输出为空或为旧值,说明脚本在子 shell 运行(sh 方式);若输出为新值,说明在当前 shell 运行(source 方式)。

检查 shell 层级

使用 echo $SHLVL 命令查看 shell 层级。在当前 shell 执行 echo $SHLVL 记录数值,然后在脚本中也 echo $SHLVL。source 执行时脚本内层级与当前一致,sh 执行时脚本内层级比当前高 1。

常见坑

环境变量失效和权限错误是最高频问题,操作前需确认以下边界。

Shell 脚本中 source 执行与 sh 执行脚本环境变量区别是什么?

1. 脚本中 cd 命令无效

使用 sh 执行脚本时,脚本内的 cd 命令只在子 shell 生效,脚本结束后当前终端目录不变。若需切换当前终端目录,必须使用 source 执行脚本。

2. 别名 alias 不生效

在脚本中定义 alias 并使用 sh 执行,当前 shell 无法使用该别名。加载别名配置文件(如 .bashrc)必须使用 source。

3. 误用 ./ 执行配置脚本

./script.sh 默认启动子 shell,行为同 sh。若误用此方式执行环境配置脚本,会导致后续命令找不到变量或路径,需改为 source ./script.sh。

常见问题

sh 执行脚本后变量能保留吗?

不能保留。sh 启动子进程,脚本中定义的变量在进程结束后销毁,除非使用 export 导出且父进程主动获取,否则当前 shell 无法感知。

source 命令需要脚本有执行权限吗?

不需要。source 是 shell 内建命令,直接读取文件内容,只要当前用户有文件读取权限(r 权限)即可执行。

点号.和 source 命令一样吗?

一样。点号.是 source 命令的简写形式,功能完全相同,. script.sh 等同于 source script.sh。

参考来源

  • 深入理解 source 和 sh、bash 的区别
  • source 与 sh 的区别
  • source 和 sh 的区别
  • linux shell 脚本 sh 和 source 区别
  • shell 中 source 命令与 sh 命令的区别
  • Shell 脚本执行方式解析:source、sh 与直接执行的区别
  • Linux 之 Shell 脚本编程—— sh 与 source (. ) 区别 (3)
  • Shell 编程-`--source` 和 ./ 和 sh 运行脚本的区别 & 更新环境变量
  • 详解 shell 中 source、sh、bash、./执行脚本的区别