先看表格:
| 执行方式 | 是否创建子 Shell(所有区别的根源) | 是否遵守 Shebang(即脚本开头的: #!/bin/bash #!/bin/sh) | 是否需要执行权限 | 变量是否生效到当前终端 | 核心特点 | 适用场景 |
|---|---|---|---|---|---|---|
sh xx.sh | ✅ 是 | ❌ 无视 | ❌ 不需要 | ❌ 不生效 | 强制 sh 执行,阉割版语法 | 极简脚本临时测试 |
bash xx.sh | ✅ 是 | ❌ 无视 | ❌ 不需要 | ❌ 不生效 | 强制 bash 执行,全语法支持 | bash 脚本临时测试(推荐) |
./xx.sh/ 绝对路径 | ✅ 是 | ✅ 严格遵守 | ✅ 必须要有 | ❌ 不生效 | 标准化执行,最规范 | 生产环境正式运行(首选) |
. xx.sh | ❌ 否 | ❌ 无视 | ❌ 不需要 | ✅ 永久生效 | 当前 Shell 执行,等价 source | 加载环境变量 / 函数库 |
source xx.sh | ❌ 否 | ❌ 无视 | ❌ 不需要 | ✅ 永久生效 | 当前 Shell 执行,等价. | 加载环境变量 / 函数库 |
方式1:sh 脚本名.sh 执行
执行原理
强制调用系统的 /bin/sh 解释器来执行脚本,完全无视脚本开头的 Shebang 行(哪怕你写了#!/bin/bash也没用)。
在绝大多数 Linux(Ubuntu/Debian/CentOS)中,不是独立的 Shell,是一个软链接:
- Ubuntu/Debian:
/bin/sh -> dash(轻量级 Shell,精简、速度快,但砍掉了 bash 的所有高级语法,比如pipefail) - CentOS7+/RHEL:
/bin/sh -> bash(但会强制 bash 以「POSIX 兼容的精简模式」运行,依然不支持pipefail等高级选项)
方式2:bash 脚本名.sh 执行
执行原理
强制调用系统的 /bin/bash 解释器来执行脚本,同样无视脚本开头的 Shebang 行。
/bin/bash:GNU Bash,功能完整的主流 Shell,支持set -euo pipefail、数组、正则、管道错误检测等所有高级语法,兼容性强、功能丰富,是生产环境首选
方式3:路径执行 ./脚本名.sh 或 /绝对路径/脚本名.sh
原理:
这是 Linux 最标准、最规范的脚本执行方式,核心规则:
严格遵守脚本开头的 Shebang 行声明!
脚本写
#!/bin/bash就用 bash 执行,写#!/bin/sh就用 sh 执行,写#!/usr/bin/python3就用 python3 执行,完全按声明来。
前置条件(必须!)
脚本必须拥有执行权限,否则会报 Permission denied 权限不足错误,添加权限命令:
chmod +x small_libary.sh
方式 4:. 点执行 . 脚本名.sh (注意:点和脚本之间有空格!)
方式 5:source 脚本名.sh 执行
核心重点:. 和 source 是【完全等价】的!
结论先行:在所有 Shell 环境中,
. 脚本.sh=source 脚本.sh,两者没有任何区别,只是写法不同!
执行原理
不调用任何解释器,也完全无视 Shebang 行,直接在「当前的 Shell 环境」中逐行执行脚本里的所有命令。
总结(核心知识点,背下来,终身受用)
记住 3 个核心分类,所有执行方式一目了然
- 子 Shell 执行(变量不生效):
sh xx.sh、bash xx.sh、./xx.sh- 三者共性:脚本运行在独立进程,执行完变量消失,互不影响当前终端;
- 优先级推荐:
bash xx.sh(临时测试) >./xx.sh(生产正式运行) >sh xx.sh(尽量不用)
- 当前 Shell 执行(变量永久生效):
. xx.sh=source xx.sh- 唯一用途:加载环境变量、函数库、配置文件,这是它们的专属场景,无可替代!
黄金执行法则(按场景选择,永不踩坑)
- 写好 bash 脚本,想临时测试运行 → 用
bash 脚本.sh - 脚本开发完成,想正式上线运行 → 加执行权限后用
./脚本.sh - 脚本里写了环境变量 / 函数 / 配置,想让配置生效 → 用
. 脚本.sh或source 脚本.sh - 永远不要用
sh 脚本.sh执行 bash 脚本,除非脚本极简到只有 echo 和 cd 命令!
Comments NOTHING