惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
S
Schneier on Security
P
Proofpoint News Feed
The Cloudflare Blog
S
SegmentFault 最新的问题
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
雷峰网
雷峰网
博客园 - 【当耐特】
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
F
Fortinet All Blogs
宝玉的分享
宝玉的分享
博客园 - 聂微东
Engineering at Meta
Engineering at Meta
G
Google Developers Blog
Know Your Adversary
Know Your Adversary
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
CXSECURITY Database RSS Feed - CXSecurity.com
G
GRAHAM CLULEY
T
Threatpost
T
Threat Research - Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
Latest news
Latest news
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
SecWiki News
SecWiki News
L
LangChain Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The Last Watchdog
The Last Watchdog
阮一峰的网络日志
阮一峰的网络日志
Security Latest
Security Latest
P
Palo Alto Networks Blog
L
LINUX DO - 最新话题
博客园 - 司徒正美
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Privacy International News Feed
N
News and Events Feed by Topic
Spread Privacy
Spread Privacy
T
Tenable Blog
有赞技术团队
有赞技术团队
MyScale Blog
MyScale Blog
aimingoo的专栏
aimingoo的专栏
AI
AI

码云笔记

Pinia v4 发布:Vue 状态管理进入新时代 Linux LVM:故障排查与数据恢复指南 Java中wait()与sleep()方法的不同点是什么? Bonsai27B 重磅落地!27B 大模型实现手机本地运行 ES2026 第 17 版新增的 5 个新特性 高德重磅上线 ABot‑World Studio,消费级显卡就能搭建专属 3D 虚拟世界 Java中final、finally和finalize的区别是什么? 怎么修改Ollama及其模型的默认路径?Ollama路径修改、迁移与重启的操作教程 iOS27 公开测试版正式上线!AI Siri 与液态玻璃成最大看点 Yuku正式发布!比 Vite+ 快 5.4 倍的前端工具链 Linux lsof 命令详解:进程与文件监控实战 Claude Code CLI命令手册 代码审查重构Bug修复场景化工作流 OpenClaw中连接并使用本地Ollama模型的操作教程 GPT-5.6 今天正式上线:OpenAI 掏出”太阳系”全家桶,Sol / Terra / Luna 齐发,打的却是一张”效率牌” Nacos MySQL持久化部署完整教程 GPT-5.6系列正式上线:OpenAI以效能与性价比重塑AI行业竞争格局 Java中序列化与反序列化的概念是什么? 如何在HTML中实现字体颜色根据背景自动变化? JDK动态代理与CGLIB动态代理的区别是什么? OpenClaw数据加密敏感信息保护的完整教程 砸超亿美元算力!亚马逊秘密启动Moonraker项目,Alexa迎来颠覆性升级 PHP 最轻量、结构化 .docx 到 Markdown 转换器 Elephant TypeScript 7.0 正式发布 蚂蚁灵波开源全球首款 MoE 具身视频大模型 LingBot-Video,为机器人世界模型搭建新底座 SpaceX AI联合Cursor推出Grok 4.5 搅动专业AI赛道格局 英伟达Vera CPU落地商用,改写AI代理时代算力竞争规则 什么是端点检测与响应(EDR)以及它的工作原理介绍 Anime.js 已经 10 岁了!作者查出脑瘤,V5 将开始收费! 星链开启全面升级!SpaceX申请十万颗卫星,构建AI时代全球天基基建 PHP 通用表达式语言 CEL-PHP 2.0.0 正式发布! WordPress 7.0 下载,支持AI建站 Docker Desktop(windows)版本下载 详解 Linux 端口监听检查工具:ss、netstat、lsof 京东 JoyAI 上线 UGC 数字人功能,普通人一键打造专属虚拟分身 Java中Integer缓存池的作用是什么? 应对劳动力短缺 日本加码布局AI机器人产业,2040年拟千万台机器人落地各行各业 Java中深拷贝与浅拷贝的区别是什么? Claude旗舰模型收费规则大变:订阅权益取消,转为按量计费 MySQL中的分布式架构和复制策略 如何在 MySQL 中处理 BLOB 和 CLOB 数据类型? 如何在 MySQL 中处理和优化长时间运行的查询? git提交信息分别用什么icon好? Composer安装与配置教程 35岁华为员工偷偷面试,被面试官嘲讽:你是被淘汰的吧?他的回怼让面试官当场闭嘴 谷歌Nano Banana 2 Lite正式上线:4秒极速出图,大幅降低AI生图成本 锐捷交换机运维配置完全参考手册 Vue 3.5:Effect Scope 与响应式污染隔离机制 IS-IS协议基本概念、工作原理与扩展应用 美团LongCat-2.0重磅开源!国产万亿参数大模型解锁超长上下文新能力 LangChain4j 和 LangGraph4j 区别是什么?哪个更好? Claude Code 的聊天和配置可以一键搬进 Codex 了 码云笔记详解Markdown格式兼容性、图片显示失效与同步冲突解决 python实现自动爬取某论坛帖子并导出到Word文档的实战教程 高德低调内测 AI 零代码工具“袋马”,切入小微商家轻量化应用开发赛道 一文看懂OSPF:基础概念、工作原理和应用场景 PHP (Yii2) 接入企业级 SSO 单点登录实战教程 Google终于支持修改Gmail邮箱了?实测告诉你哪些能改,哪些不能改!(附详细教程+FAQ) UCloud 4.6 元 / 月服务器是真的吗? 2026 云服务器完整选购攻略 Webiny:无服务器应用程序框架 Fyrox:现代化的 Rust 游戏引擎 千问发布全球首个原生语言世界模型Qwen-AgentWorld,AI智能体迈入全环境实操新时代 火山引擎上新豆包音频生成模型1.0,AI音频生成实现一键全流程创作 使用Claude Code经常遇到的10个问题 如何批量清理wordpress所有文章和标签,保留设置,保留分类? 谷歌 NotebookLM 内测文献综述矩阵工具,Gemini3.5 赋能 AI 学术结构化研究 京东开源JoyAI-VL-Interaction模型 解锁AI实时视频视觉交互新形态 破解中小商家海报设计难题!MeiGen-AI开源闭环AI设计方案落地 Node Plus ?比 pnpm 快 24 倍! Plan-Execute-Replan 和 ReAct 的区别是什么? Anthropic最新报告揭秘:AI编程人机协作成开发者主流工作模式 详解PostgreSQL 18 逻辑复制冲突检测与解决方法 JDK动态代理与CGLIB动态代理的区别是什么? 详解 Linux 中 localhost、127.0.0.1 与 Loopback(回环地址) OpenAI Codex新手入门教程 安装配置AGENTS.md与MCP全流程详解 程序员必备AGENTS.md配置指南 规避AI编码修改乱象 使用 Codex 必装的 12 个插件,你值得拥有! macOS AI CLI工具安装与避坑指南 OpenClaw Gemini Claude报错全套解决方案 智谱AI正式开源GLM-5. 2 模型:主打1M无损上下文与长程代码任务 小米 MiMo Claw 正式版上线 轻量化 Agent 打通金山办公生态 如何定义 Vue 的动态路由?如何获取传过来的动态参数? 记录Claude Code Router 接入过程遇到问题及解决方法 千问AI眼镜凭硬核实力领跑2026智能穿戴赛道 程序员特有的习惯你占了几条! 郝景芳新作半数内容由AI创作,文坛郝景芳AI写作争议再起 使用 iftop、nload、bmon、vnstat 监控 Linux 网络带宽 现代富文本编辑器为什么最终都会抛弃 DOM? Vue 的 v-cloak 和 v-pre 指令有什么作用? 去哪里买抖音号?抖音小号在线购买-抖音小号出售批发 实名闲鱼小号出售|闲鱼账号批发|咸鱼发布账号|出售闲鱼发布账号 zfb号购买-支付宝小号购买-实名支付宝购买号-企业支付宝购买-支付宝小号批发 个人支付宝实名账号出售|v2/v3支付宝账号出售|实名支付宝小号购买 闲鱼账号哪里有卖-闲鱼实名账号购买的途径 Java注解的实现原理是什么? Agentation MemPalace 《置身钉内》之好词好句好段摘抄 AI有声书革命!万象有声全自动生产线,7元/万字颠覆网文有声化行业 详解CentOS 7跨版本迁移Rocky Linux9 生产环境安全升级教程 Java中序列化与反序列化的含义是什么? 18. Python 标准库之 Json 模块
详解Bash set 命令:set -e、set -x 和 set -u 完全指南
刃小木 普通 · 2026-06-22 · via 码云笔记

AI 概述

本文讲解Bash内置set命令核心参数:-e命令失败退出、-u拦截未定义变量、-x打印执行过程、pipefail捕获管道报错。推荐组合`set -euo pipefail`开启严格模式,支持局部开启/关闭调试,附带用法示例、边界坑点、查询命令与实操速记,提升脚本健壮性。

目录

文章目录隐藏

  1. 一、set 命令的作用
  2. 二、set -e:出错时立即退出
  3. 3.set -u:将未定义变量视为错误
  4. 四、set -x:逐条跟踪命令
  5. 五、set -o pipefail:捕获管道中的失败
  6. 六、组合成严格模式
  7. 七、针对代码块启用和禁用选项
  8. 八、查看当前选项
  9. 九、设置位置参数
  10. 十、快速参考
  11. 十一、常见问题解答(FAQ)
  12. 十二、总结

详解 Bash set 命令:set -e、set -x 和 set -u 完全指南

默认情况下,Bash 脚本即使某条命令执行失败,也会继续运行。变量名拼写错误会被展开为空字符串,失败的 cd 命令被忽略,脚本若无其事地继续执行,往往在最终停下来之前已经造成了实质性损害。set 内建命令改变了这一切。通过几个标志,你可以让 Bash 在遇到第一个错误时停止执行,将未定义的变量视为错误,并逐条打印执行的每条命令。

本指南详细讲解 set 命令以及你最常用的三个选项:set -eset -uset -x,此外还包括 pipefail 以及如何将它们组合成严格模式。

set 是一个 Shell 内建命令,用于开启或关闭 Shell 选项,以及设置位置参数。对于选项,它采用以下形式:

set [选项]

每个选项都有短格式和长格式。开头的减号(-) 表示开启选项,加号(+) 表示关闭选项——这与大多数人的直觉相反:

命令 含义
set -e 开启选项(此处为:出错时退出)
set +e 关闭该选项
set -o errexit set -e 的长格式
set +o errexit set +e 的长格式

通常将这些命令放在脚本顶部附近,使其对后续所有代码生效;或者放在特定代码块周围,使其仅对该部分脚本生效。

二、set -e:出错时立即退出

set -e(也写作 set -o errexit)指示 Bash 在任何命令返回非零状态码时立即退出。它可以防止脚本在失败后继续执行。

# 示例:进入目录并写日志

cleanup.sh

#!/bin/bash
set -e

cd /var/cache/myapp
printf 'Cleaning application cache\n'
  • 没有set -e:如果 cd 失败(目录不存在),脚本会继续执行,在当前所在目录中打印日志信息
  • set -e:cd 失败后脚本立即停止,日志信息和后续缓存命令都不会执行

重要例外情况set -e在以下情况下不会触发退出(这常常让人踩坑):

场景 说明
在 if、while 或 until 的条件测试中 允许测试命令的退出状态
与 && 或 || 连接的命令 用于条件链
前面带有 ! 的命令 用于反转退出状态
grep "pattern" file.txt || true

3.set -u:将未定义变量视为错误

set -u(或set -o nounset)使得 Bash 在引用未定义的变量时退出。这能捕获脚本中最常见的错误之一:变量名拼写错误导致静默展开为空字符串。

示例:部署脚本 deploy.sh

#!/bin/bash
set -u

target_dir="/srv/www"
printf 'Target cache directory: %s\n' "${tagret_dir}/cache"

变量名错误地写成了 tagret_dir:

  • 没有set -u${tagret_dir}展开为空字符串,输出/cache而非/srv/www/cache
  • set -u:Bash 立即报错并退出:
    deploy.sh: line 5: tagret_dir: unbound variable
    

处理可选变量当某个变量确实可选时,使用${VAR:-default}提供默认值,确保引用始终已定义:

echo "Deploying to ${ENVIRONMENT:-staging}"

四、set -x:逐条跟踪命令

set -x(或set -o xtrace)在执行每条命令之前将其打印到标准错误输出,并展开所有变量值。这是在不添加大量 echo 语句的情况下,精确查看脚本执行过程的最快方式。

示例:问候脚本 greet.sh

#!/bin/bash
set -x

name="Haopython"
echo "Hello, $name"

运行脚本时,每条命令前会带有 + 前缀,与正常输出一同显示:
<pre+ name=Haopython + echo ‘Hello, Haopython’ Hello, Haopython

跟踪输出显示变量已被展开,因此看到的是 Bash 实际使用的真实值。

自定义 PS4 变量

前缀来自 PS4 变量。将其设置为包含脚本名称和行号,在较长的脚本中非常有用:

PS4='+ ${BASH_SOURCE}:${LINENO}: '

只调试特定代码段由于跟踪输出信息量大,常见做法是仅在需要调试的代码段周围启用跟踪:

set -x
deploy_application
sync_assets
set +x

只有set -xset +x之间的两条命令会被跟踪输出。

五、set -o pipefail:捕获管道中的失败

默认情况下,管道命令返回的是最后一条命令的退出状态,因此管道前期的失败会被隐藏。# 示例:搜索日志文件

grep "ERROR" missing.log | wc -l

在该管道中,即使 grep 因为文件不存在而失败,wc 仍然成功,整个管道退出状态为 0(来自 wc)。set -o pipefail改变了这一行为:管道返回最右侧失败命令的状态,如果所有命令都成功则返回 0。与set -e结合使用时,管道前期的失败也能真正停止脚本的执行。

六、组合成严格模式

这些选项组合在一起效果最好。顶部常见的组合是:script.sh

#!/bin/bash
set -euo pipefail

这一行同时启用了:

  • 出错时退出(-e);
  • 未定义变量检查(-u);
  • 管道失败检测(pipefail)。

调试时再加上 -x:set -euxo pipefail,调试完成后移除 -x。

这种模式是所谓的 “Bash 严格模式” 的基础。

七、针对代码块启用和禁用选项

不必将选项应用于整个脚本。可以在某个代码块中开启,之后关闭。这在跟踪调试时很常见:

set -x
deploy_application
sync_assets
set +x

只有set -xset +x之间的两条命令会被跟踪。同样的模式也适用于set -e,当需要手动处理某个部分的错误时非常有用。

八、查看当前选项

不带任何标志运行set -o会列出所有选项及其开关状态。完整列表有二十多个条目,本文讨论的四个选项如下:

set -o

输出示例:

errexit         off
nounset         off
pipefail        off
xtrace          off

这是快速确认交互式 Shell 或已 source 的脚本启用了哪些选项的方法。

九、设置位置参数

set 命令还有与选项无关的第二项功能:当在 — 之后给出参数时,它会替换位置参数$1、$2 等。当想重置脚本或函数读取的参数时,这非常有用:

set -- one two three
echo "$2"

输出:

two

— 标记选项结束,确保以减号开头的参数不会被误认为是选项标志。

十、快速参考

选项 长格式 作用
set -e set -o errexit 命令失败时立即退出
set -u set -o nounset 使用未定义变量时报错
set -x set -o xtrace 执行前打印每条命令
set -o pipefail set -o pipefail 管道中任一命令失败则管道失败
set +e set +o errexit 关闭选项(用加号代替减号)
set -o 列出所有选项及其状态
set — a b c 设置位置参数

十一、常见问题解答(FAQ)

Q1:set -e 和 set -o errexit 有什么区别?

没有区别。set -e是短格式,set -o errexit是更长、更具可读性的长格式。选择你喜欢的即可;长格式在共享脚本中更常见,因为它们具有自文档性。

Q2:为什么我的脚本在 set -e 开启后,命令失败仍然继续执行?

失败的命令可能位于以下位置:

  • if、while 或 until 的条件测试中;
  • 与 && 或 || 连接的命令;
  • 前面带有 ! 的命令。

在这些位置,Bash 故意忽略失败,以便你可以测试退出状态。命令替换或函数调用也可能掩盖失败。

Q3:set +x 中的加号是什么意思?

加号(+)关闭,减号(-)开启的选项。set -x开启跟踪,set +x关闭跟踪,因此你可以将选项作用域限定在脚本的某一部分。

Q4:我是否应该始终使用 set -euo pipefail?

这是新脚本的良好默认设置,可以及早捕获许多错误。但set -e本身有一些令人意外的边界情况。对于复杂脚本,请了解每个选项的行为,并显式处理异常情况,而不是假定脚本完全受到保护。

十二、总结

set 内建命令将 Bash 从宽容的 Shell 转变为严谨的 Shell:

选项 作用
set -e 出错时停止
set -u 捕获变量名拼写错误
set -x 精确显示执行内容

将它们组合为set -euo pipefail放在脚本顶部,将跟踪调试限定在需要调试的代码块范围内,这样脚本将尽早地报错,而不是悄无声息地做错事。

命令速记卡片:

set -e              # 出错时退出
set -u              # 未定义变量报错
set -x              # 跟踪执行命令
set -euo pipefail   # 严格模式(推荐)
set +x              # 关闭跟踪
set -o              # 查看所有选项
set -- a b c        # 设置位置参数

灵活使用 set 系列参数,可彻底优化 Bash 脚本默认的宽松执行逻辑,提前拦截命令报错、变量错误、管道执行异常等各类隐患。以set -euo pipefail构建脚本严格模式,搭配局部开关实现精准调试,能够显著提升脚本的健壮性、可维护性与排错效率,是开发稳定可靠 Bash 脚本的核心最佳实践。

以上关于详解Bash set 命令:set -e、set -x 和 set -u 完全指南的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 详解Bash set 命令:set -e、set -x 和 set -u 完全指南