何时使用
适用:为 shell 脚本搭建 lint 基础设施、在 CI/CD 流水线对脚本做质量门禁、读懂并修复 ShellCheck 告警、为项目定制规则集(开启/关闭检查)、抑制误报、推进脚本通过质量门、保障跨 shell 可移植性。
不该用(负边界):
- 任务与 shell 脚本的静态检查无关(如运行期单元测试、性能压测)。
- 需要的是另一种语言/工具的 linter(Python 用 ruff、JS 用 eslint 等)。
- 把 ShellCheck 输出当成环境相关验证的替代品——它是静态分析,不替代实跑测试与专家评审。
步骤
- 安装并核对版本:
shellcheck --version。 - 在项目根放
.shellcheckrc,固定目标 shell 方言(shell=bash或sh),集中管理开关。 - 本地逐个或并行扫描脚本,按 SC 码定位问题。
- 优先按修复原则改代码,而非一律
disable;确需抑制的写行内注释并注明理由。 - 接入 pre-commit 钩子(提交前拦截)与 CI(合并前门禁),
--format=gcc/json便于机器解析。
决策:能改就改(引号、if 判断退出码等);规则性误报(如未跟随 source 文件 SC1091)才整体关闭,并在配置里写明原因。
指令
安装:
brew install shellcheck # macOS
apt-get install shellcheck # Ubuntu/Debian
shellcheck --version # 校验
.shellcheckrc(项目级,放仓库根):
shell=bash
enable=avoid-nullary-conditions,require-variable-braces,check-unassigned-uppercase
# SC1091:不跟随 source 文件,误报多
disable=SC1091
# SC2119:参数调用风格提示
disable=SC2119
external-sources=true
常见命令档位:
# 严格可移植(按 sh 检查、跟随 source)
shellcheck --shell=sh --external-sources --check-sourced script.sh
# Bash 开发(开全部检查 + 精选排除)
shellcheck --shell=bash --enable=all --exclude=SC1091,SC2119 script.sh
# CI 门禁:扫全部 .sh,发现问题即失败
find . -type f -name "*.sh" -print0 | xargs -0 -P4 -n1 shellcheck --format=gcc
抑制误报(务必注明原因,能改勿关):
# shellcheck disable=SC2086 # 仅对下一行生效
# shellcheck source=./helper.sh
source helper.sh
输出格式:--format=gcc(CI 友好)、--format=json(程序解析)、--format=quiet(仅靠退出码)。
示例
pre-commit 钩子(.git/hooks/pre-commit,只检查本次改动的脚本):
#!/bin/bash
set -e
git diff --cached --name-only | grep '\.sh$' | while read -r script; do
if ! shellcheck "$script"; then
echo "ShellCheck failed on $script"; exit 1
fi
done
GitHub Actions:
name: ShellCheck
on: [push, pull_request]
jobs:
shellcheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run ShellCheck
run: |
sudo apt-get install shellcheck
find . -type f -name "*.sh" -exec shellcheck {} \;
典型告警与修法:
# SC2086 加引号防分词/通配 for i in "${list[@]}"; do ... done
# SC2181 直接判退出码 if some_command; then ... fi
# SC2015 用 if 而非 && || if [ -f "$f" ]; then ...; else ...; fi
# SC2016 单引号不展开变量 echo "value: $VAR"
# SC2009 用 pgrep 代替 grep pgrep -f myprocess
注意事项
- 务必按目标 shell 检查(别拿 bash 当 sh 分析),否则误报/漏报。
- 排除规则要在配置里写注释说明缘由;尽量改代码而非关告警。
--enable=all配合谨慎排除可获得最严检查;定期升级 ShellCheck 以获取新规则。- 大批量脚本用
xargs -P并行或对结果做哈希缓存提速。 - 缺少输入、权限或验收标准时先停下澄清,别用静态结果替代实跑验证。
- 参考:ShellCheck 仓库 https://github.com/koalaman/shellcheck ;Wiki(按 SC 码查解释)https://www.shellcheck.net/wiki/ 。
互见
- related:
bash-defensive-patterns—— 防御式 Bash 编码,ShellCheck 是其落地的检查器 - combines_with:
ci-cd-pipeline-builder—— 把脚本检查接入流水线门禁 - combines_with:
pre-commit/Git 钩子类技能 —— 提交前本地拦截
采编自 sickn33/antigravity-awesome-skills(MIT)。