模块S12 调试、测试与排错篇号S12-01 / 42预计阅读45 分钟主线Bash文章目录本篇目标30 秒速览正文1. 与 S01-04 的关系2. set -x 打印的是什么3. 三种开启方式4. PS4定制跟踪前缀5. 把跟踪写到文件可选6. set -v 与 set -x 对照7. 与 set -e 一起读日志8. 缩小跟踪范围8.1 块内开关8.2 仅调试模式8.3 子 shell 继承9. 敏感信息与产线10. 读 日志的套路11. 常见误区12. 与其它篇的衔接读脚本检查清单练习判断题实操题改错题下一篇预告本篇目标系统化使用set -xxtrace与PS4排错看清变量展开后实际执行的命令。会写局部跟踪、bash -x、自定义PS4带行号/函数名并知道set -v的区别、敏感信息与set -e下如何读日志。衔接S01-04入门本篇加厚实战。30 秒速览set -x执行前把展开后的命令打到stderr行前常带。set x关闭bash -x script.sh不改文件整脚本跟踪。PS4自定义前缀常加$LINENO、${FUNCNAME[0]}。set -v打印读入的源行不是展开后命令少用。产线不要常开-x泄密、日志爆炸用VERBOSE或局部块。跟踪输出是stderr别当成业务 stdout。正文1. 与 S01-04 的关系S01-04 已介绍set -x/set -v入门。本篇补充主题S01-04S12-01开启/关闭✅复习 场景PS4预告详讲bash -x✅组合环境变量与set -e排错略实例缩小跟踪范围—函数/块2.set -x打印的是什么set-xuseradminfile/tmp/my report.txtgrepERROR$filesetx可能看到示意 useradmin file/tmp/my report.txt grep ERROR /tmp/my report.txt读跟踪日志来自PS4默认多为。看到的是展开后命令不是你在编辑器里敲的原文。适合查变量空了吗路径引号对吗实际参数有几个3. 三种开启方式# 1. 脚本内set-xsuspect_codesetx# 2. 不改脚本bash-x./deploy.sh arg1# 3. 环境当前 shell 子进程继承exportPS4(${BASH_SOURCE}:${LINENO}): bash-x./deploy.sh方式何时用局部set -x只怀疑某一段bash -x快速看全流程、CI 复现VERBOSE分支S06-03(( VERBOSE )) set -x4.PS4定制跟踪前缀PS4是 xtrace 的提示符类似PS1之于交互提示。exportPS4(${BASH_SOURCE##*/}:${LINENO}:${FUNCNAME[0]:-main}): set-xmain$输出可能像(deploy.sh:42:main): cmdfoo (deploy.sh:43:main): echo foo变量含义$LINENO当前行号${BASH_SOURCE[0]}当前文件${FUNCNAME[0]}当前函数名顶层常为空用: -main占位函数内exportPS4[${FUNCNAME[0]}:${LINENO}] 读他人脚本见到很长的PS4说明作者要带上下文的跟踪。5. 把跟踪写到文件可选默认 xtrace 走stderr。可改 fdBashexportBASH_XTRACEFD7exec7debug.logset-x日常更常见bash -x script.sh 2trace.log。6.set -v与set -x对照set-vxa becho$xsetv选项打印-v读入的源行echo $x-x展开后echo a b可能拆词排错优先-x-v适合看「Shell 实际读到了哪一行」续行、引号错误衔接 S02-02。7. 与set -e一起读日志set-euopipefailset-xfalseechonever跟踪里会出现 false然后脚本退出echo never的不会出现。管道配合pipefailS09-02set-euopipefailset-xfalse|trueechoafterpipefail下可能无 echo after。用 xtrace 判断停在哪条命令。8. 缩小跟踪范围8.1 块内开关f(){set-xlocalx$1process$xsetx}8.2 仅调试模式[[${DEBUG:-}1]]set-x# 或((VERBOSE))set-x8.3 子 shell 继承(set-x;inner_cmd)# 子 shell 内跟踪结束后父 shell 仍关闭9. 敏感信息与产线-x会打印密码、token 参数curlURL 里的密钥环境变量展开不要在产线长期set -x。临时排错后set x或去掉bash -x。# 避免set-xcurl-HAuthorization: Bearer$TOKEN...可对可疑段手动echo脱敏再开 xtrace。10. 读日志的套路从最后一条命令往前看哪条没出现下一条即失败或退出点。对比展开后参数个数与预期$是否变成多个词。[/[[/((在-x里也会展开可核对条件。函数调用看PS4是否进入子函数。与echo $?S04-01配合关-x后单独测或trap echo ERR $LINENO ERRS11-01。11. 常见误区误区说明把行当正常输出走 stderr重定向要分开常开-x当审计用结构化日志不用 xtrace忘记set x后面日志全泄露只看源行不看展开应用-x不是-v在source的库里开-x污染当前终端S08-0312. 与其它篇的衔接篇目衔接S02-02续行/缩进在-v下更易见S04-01跟踪后查$?S06-03VERBOSE set -xS12-02ShellCheck 静态查-x动态查S12-03最小复现 -x二分读脚本检查清单是否用PS4带了文件/行号DEBUG/VERBOSE才开-x还是写死常开跟踪是否可能打印密钥排错完是否set x用的是bash -x还是脚本内set -x练习判断题set -x打印的是展开后的命令。PS4默认与PS1相同。bash -x script.sh等价于在 script.sh 第一行写set -x效果接近继承环境略有差异。xtrace 输出默认在 stdout。set x关闭 xtrace。参考答案对。错默认多为。对大致等价用于排错。错stderr。对。实操题写片段PS4含行号对namea b执行echo $name与echo $name用set -x观察行差异。参考答案要点无引号时可能看到 echo a b两条词有引号时 echo a b或 echo a b一次参数。说明S02-01引号在展开后的可见性。改错题#!/usr/bin/env bashset-euopipefailset-xAPI_KEYsecretcurl-HAuthorization: Bearer$API_KEYhttps://api.example.com# 产线长期保留 set -x列出至少 2 处问题。参考产线/提交代码中不应常开set -x泄露API_KEY。排错后应set x或改为[[ $DEBUG 1 ]] set -x。日志应脱敏避免 Bearer token 进 trace。下一篇预告S12-02《语法检查与 ShellCheck静态发现问题》— 不运行脚本也能查引号、set、常见坑。