要用当前 shell 环境执行脚本,必须使用 source 或 . 命令;它们将脚本内容逐行读入当前 shell 执行,使变量、函数、环境修改等立即生效,不启动子 shell。

要用当前 Shell 环境执行脚本(不启动子 Shell),核心方法就是用 source 或等价的点命令 .。这能确保脚本里定义的变量、函数、别名、环境修改(比如 PATH、PS1)直接生效于当前会话,而不是运行完就消失。
为什么不用 ./script.sh 或 bash script.sh?
这两种方式都会创建一个新的子 Shell:
-
./script.sh:需要执行权限,用脚本首行#!/bin/bash指定解释器,在新进程中运行; -
bash script.sh:显式调用 bash 启动子进程,无论脚本有没有可执行权限; - 子 Shell 中设置的变量(如
export MY_VAR=1)不会传回父 Shell,执行完就清空。
正确做法:用 source 或 .
语法完全等价,任选其一即可:
source script.sh-
. script.sh(注意点号后要加空格)
它们都表示“把脚本内容逐行读入当前 Shell 执行”,不产生新进程。常见典型场景包括:
- 重载配置文件:
source ~/.bashrc让新添加的 alias 或 export 立即生效; - 临时加载函数库:
. ./utils.sh,之后就能直接调用其中定义的函数; - 调试环境变量变更:在脚本里写
export DEBUG=1,用source执行后,当前终端立刻能用$DEBUG。
注意事项和常见误区
实际使用时容易踩坑的地方:
- 路径必须写对:如果脚本不在当前目录,要写相对或绝对路径,例如
source ~/myenv.sh; - 脚本无需可执行权限:
source不依赖x权限,但需有读取权限(r); - 别混淆
.和./:./script.sh是执行子 Shell,. script.sh才是当前 Shell 加载——少一个斜杠,行为完全不同; - 脚本第一行
#!/bin/bash在source时会被忽略,实际用的是当前 Shell 的解释器(通常是 bash),所以不必严格匹配。
替代方案对比:exec 不适合这个需求
exec script.sh 虽然也不开子 Shell,但它会**替换当前 Shell 进程**,执行完脚本后整个 Shell 就退出了,无法继续输入命令。所以它不适合“加载配置”这类需要保留当前会话的场景,仅用于彻底切换进程(如启动服务主程序)。











