📌 问题
在一些 Shell 脚本中,常常看到以下结构:
#!/usr/bin/env bash
{ # this ensures the entire script is downloaded #
# 脚本内容
some_function() {
echo "Hello"
}
some_function
} # this ensures the entire script is downloaded #
为什么要用 { ... }
把整个脚本包裹起来?这样做有什么好处?
✅ 答案
这是一个 Shell 脚本技巧,主要用于:
确保整个脚本在下载完成并被完全解析之后再执行
🧠 原因解释
在执行远程脚本时,例如:
curl -s https://example.com/script.sh | bash
脚本是以流式方式传给 bash
的,会出现:
- 边下载边执行
- 如果下载中断,脚本会只执行了一部分
- 函数定义、变量赋值可能不完整,甚至执行危险命令
🛡 加上 { ... }
的作用
使用大括号包裹:
{
# 所有脚本内容
}
等于告诉 bash
:
先把整个代码块读完并确认语法完整后再执行,否则不执行。
这样做能显著提升远程执行脚本时的稳定性与安全性。
📦 使用场景
- 在线安装脚本(nvm、rustup、rvm 等)
- 托管在 GitHub/Gitee 的
curl | bash
脚本 - 对完整性有要求的初始化脚本
✅ 示例对比
❌ 没有使用 {}
(可能部分执行)
#!/usr/bin/env bash
setup_env
# 假设这里还没下载完或中断
install_dependencies
如果网络中断,
bash
已经开始执行setup_env
,但后续内容丢失。
✅ 使用 {}
(确保完整执行)
#!/usr/bin/env bash
{
setup_env
install_dependencies
}
Shell 会完整解析完
{}
里的内容后,才开始执行其中的命令。
✍ 总结
使用
{ ... }
包裹整个脚本体是一种防御式编程技巧,适用于通过管道执行的脚本(如curl | bash
),可以避免部分执行带来的错误或风险。
建议你在所有在线执行脚本中使用这种结构,尤其是涉及部署或安装操作时。