
模块S12 调试、测试与排错篇号S12-02 / 42预计阅读45 分钟主线Bash文章目录本篇目标30 秒速览正文1. 静态检查 vs 动态调试2. bash -n仅语法3. 安装与基本用法4. 输出长什么样5. 高频 SC 与专栏篇目对照6. 示例改前 / 改后6.1 SC20866.2 SC21646.3 SC21816.4 SC20467. source 与 SC10908. 抑制某条规则慎用9. 与 set 选项10. 工作流建议11. ShellCheck 不能发现什么读脚本检查清单练习判断题实操题改错题下一篇预告本篇目标会用ShellCheck在不运行脚本的情况下发现引号、set、管道、可移植性等问题。能读懂SC 编号提示、用shellcheck命令与编辑器集成并知道何时该改、何时可 disable。专栏其它篇不写 SC 小节本篇集中讲工具与 S12-01 动态-x互补。30 秒速览bash -n只查语法不查逻辑与引号坑。ShellCheck静态分析报SCxxxx编号与说明。安装apt install shellcheck、brew install shellcheck或 shellcheck.net。常用shellcheck script.sh指定 shell-s bash跟踪source-x。高频 SC2086未引号变量、2164cd失败、2181误用$?、2046命令替换未引号。disable要有理由不要为消警告而乱关检查。正文1. 静态检查 vs 动态调试手段何时本篇 / 篇目ShellCheck保存/提交前S12-02set -x运行结果不对S12-01最小复现仍不清楚S12-03shellcheckdeploy.sh不执行脚本只分析文本。2.bash -n仅语法bash-nscript.sh发现if未闭合、引号不配等解析错误不发现未引号变量、set -u风险、管道逻辑问题习惯bash -n ShellCheck一起用。3. 安装与基本用法# Debian/Ubuntusudoaptinstallshellcheck# macOSbrewinstallshellcheck# 检查单文件shellcheckdeploy.sh# 明确按 Bash 规则推荐本专栏脚本shellcheck-sbashdeploy.sh# 跟踪 source 路径分析被 source 的库shellcheck-x-sbashmain.sh在线把脚本贴到shellcheck.net勿贴含密钥的产线脚本。4. 输出长什么样deploy.sh:12:8: warning: Double quote to prevent globbing and word splitting. [SC2086] rm -f $tmp ^--^部分含义行:列位置warning/error/info/style严重级别SC2086规则编号可查 wiki下文说明与建议严重级别级别建议error尽量修warning多数应修info/style视团队规范5. 高频 SC 与专栏篇目对照读 ShellCheck 报告时可联想到专栏哪篇讲过SC典型提示专栏SC2086变量应双引号S02-01、S02-03SC2046$(cmd)结果应引号S09-03、S07-01SC2068$应引号S03-03SC2164cd dir失败未处理S05-02、S11-02SC2181用if cmd别只看$?S04-01SC2006用$( )别用反引号S09-03SC2154变量未赋值就引用S03-01、set -uS01-04SC2155local var$(cmd)掩码退出码S08-02SC2034变量「未使用」可能误报export、readSC1090无法跟踪source非常量路径S08-03SC3043pipefail在sh不可用S13 可移植SC2015set -e下A B || C注意S04-026. 示例改前 / 改后6.1 SC2086# 警告rm-f$tmp# 修复rm-f--$tmp6.2 SC2164# 警告cd$dirdo_work# 修复cd$dir||exit1do_work6.3 SC2181# 警告mycmdif[[$?-eq0]];then...# 修复ifmycmd;then...6.4 SC2046# 警告forfin$(ls*.log);do# 更好专栏 S07-01forfin*.log;do7.source与 SC1090source${SCRIPT_DIR}/lib/common.shShellCheck 可能报SC1090无法解析非常量 source。处理# 分析主脚本时跟踪 sourceshellcheck-x-sbashmain.sh# 或单独检查库shellcheck-sbashlib/common.sh读脚本SC1090 不是运行时错误是静态分析范围限制。8. 抑制某条规则慎用# 单行# shellcheck disableSC2034UNUSED_FOR_EXPORT1# 下一行# shellcheck disableSC2086evallegacy_code# 仅当确知安全且有注释说明原则先修再 disabledisable 旁写原因不要disableSC2086整文件9. 与set选项ShellCheck 理解常见写法会提示set -e与cmd cmd || other组合SC2015set -u与未定义变量set -o pipefail在#!/bin/sh脚本SC3043#!/bin/shset-opipefail# SC3043POSIX sh 未必支持→ 改shebang 为 bash或去掉 pipefailS13。10. 工作流建议阶段动作编辑时VS Code/CursorShellCheck 扩展波浪线提交前shellcheck -s bash *.shCI流水线跑 shellcheckerror 失败排错时ShellCheck 通过后仍用S12-01-xfindscripts-name*.sh-print0|xargs-0shellcheck-sbash11. ShellCheck 不能发现什么业务逻辑错删错文件但语法对运行时网络/权限复杂依赖顺序所有可移植性需 S13 多环境测静态 运行结合。读脚本检查清单仓库是否约定ShellCheck/ CI报告SC2086/2046是否已修引号SC2164cd是否|| exitdisable是否有注释理由shebang 与-s bash是否一致练习判断题bash -n能发现$var未加引号的风险。SC2086 通常建议给变量加双引号。shellcheck -s bash按 Bash 规则分析。SC1090 表示 source 的文件一定不存在。专栏只在 S12-02 集中讲 SC 编号其它篇用通用表述。参考答案错。对。对。错常是静态分析跟不进动态路径。对本篇为工具专篇。实操题对下面片段说出 ShellCheck最可能报哪类 SC不必跑工具tmp$(mktemp)cd$tmpdirrm-f$tmp参考答案SC2086$tmpdir、$tmp未引号。SC2164cd无|| exit。若tmpdir未定义还有SC2154set -u 运行时也会炸。改错题#!/usr/bin/env bashset-efiles$(ls*.log)forfin$files;dogreppattern$f|wc-ldone参考#!/usr/bin/env bashset-euopipefailshopt-snullglobforfin*.log;dogrep-Fpattern --$f|wc-ldone消除SC2046/2086/2006类问题grep字面用-Fpipefail按需。下一篇预告S12-03《排错方法论最小复现与二分定位》— 完成 S12 模块练「读一段卡住的脚本」。