plugins/languages/bash/skills/tooling/SKILL.md
Bash tooling chain: ShellCheck (SC codes & suppressions), shfmt (formatting style), bash-language-server LSP, bashdb / bash -x tracing, pre-commit hooks, editor integration, and shell linting in CI. Use when setting up project quality gates, configuring editors, or upgrading existing scripts to meet modern standards. Triggers on "shellcheck 配置", "shfmt 格式", "bash LSP", "shell 预提交", ".shellcheckrc", "shell 编辑器".
npx skillsauth add lazygophers/ccplugin bash-toolingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| 工具 | 角色 | 安装 |
|------|------|------|
| shellcheck | 静态检查 | brew install shellcheck / apt install shellcheck |
| shfmt | 格式化 | brew install shfmt / go install mvdan.cc/sh/v3/cmd/shfmt@latest |
| bash-language-server | LSP | npm i -g bash-language-server |
| bats-core | 测试 | brew install bats-core |
| kcov | 覆盖率 | brew install kcov / apt install kcov |
| bashdb | 交互调试 | brew install bashdb |
.shellcheckrc(项目根)# 启用所有可选检查
enable=all
# 关闭:本项目允许
disable=SC2086 # 字段分割(在确实需要展开时手动 disable)
# 默认 shell
shell=bash
# 允许 source 跟随
external-sources=true
# shellcheck shell=bash
# shellcheck source=lib/util.sh
. "$(dirname "$0")/lib/util.sh"
# 单行抑制(附理由)
# shellcheck disable=SC2086 # intentional word splitting
cmd $args
| SC | 含义 | 修法 |
|----|------|------|
| SC2086 | 未引号变量 | "${var}" |
| SC2155 | declare + 赋值掩盖退出码 | 分两行 |
| SC2164 | cd 未检查失败 | cd foo \|\| exit |
| SC2317 | 不可达代码(trap 误判) | 加注释或 disable |
| SC1091 | source 文件未找到 | 加 # shellcheck source=path |
| SC2046 | $(cmd) 未引号 | "$(cmd)" |
| SC2207 | 数组从命令读取 | 用 mapfile -t |
| SC2250 | ${var} 推荐 | 始终用大括号 |
shfmt -i 4 -ci -bn -sr -d script.sh
| 选项 | 含义 |
|------|------|
| -i 4 | 缩进 4 空格 |
| -ci | switch case 缩进 |
| -bn | 二元运算换行前置 |
| -sr | redirect 操作符后留空格 |
| -d | 显示 diff(不修改) |
| -w | 原地写入 |
.editorconfig[*.{sh,bash,bats}]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
~/.config/<editor>/lsp.json(VSCode / Neovim / Helix):
VSCode 装 mads-hartmann.bash-ide-vscode;Neovim 用 nvim-lspconfig 注册 bashls。
# 内置 trace
bash -x script.sh # 全程展开
PS4='+ ${BASH_SOURCE}:${LINENO}: ' # 更友好的 trace 前缀
set -x # 脚本内开启
set +x # 关闭
# bashdb 交互
bashdb script.sh
# (bashdb) break 42
# (bashdb) run
# (bashdb) step / next / print var
# VS Code Bash Debug 扩展(基于 bashdb)
.pre-commit-config.yaml:
repos:
- repo: https://github.com/koalaman/shellcheck-precommit
rev: v0.10.0
hooks:
- id: shellcheck
args: ["-x"]
- repo: https://github.com/scop/pre-commit-shfmt
rev: v3.8.0-1
hooks:
- id: shfmt
args: ["-i", "4", "-ci", "-w"]
- repo: https://github.com/bats-core/bats-core
rev: v1.11.0
hooks:
- id: bats
files: \.bats$
# .github/workflows/shell.yml
name: shell-quality
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: ludeeus/action-shellcheck@master
with:
severity: warning
check_together: 'yes'
- name: shfmt check
uses: mfinelli/setup-shfmt@v3
- run: shfmt -d -i 4 -ci .
project/
├── .shellcheckrc
├── .editorconfig
├── .pre-commit-config.yaml
├── .github/workflows/shell.yml
├── bin/ # 可执行脚本
├── lib/ # 被 source 的库 (.sh)
├── tests/ # bats 测试
└── Makefile
Makefile 入口:
.PHONY: lint fmt test cov
lint:
shellcheck bin/* lib/*.sh
fmt:
shfmt -i 4 -ci -w bin/ lib/
test:
bats --recursive tests/
cov:
kcov --include-pattern=.sh coverage bats tests/
.shellcheckrc 已配置(shell + 例外)shfmt -d 零 diffshellcheck 零警告(warning 级以上)development
Go 数据库规范——GORM Model 命名 ModelXxx、表名单数、枚举 uint8 + 常量、索引 idx_ 前缀 + deleted_at leading column、禁 time.Time 统一 int64 unix、禁指针/nullable 字段、TEXT/BLOB/JSON 禁 default、AutoMigrate 禁改主键。设计 DB model、写 GORM tag、建索引、做 migration 审查时触发。
development
Go HTTP API 规范——响应始终 200 + body code 字段、路由 /api/* 全 POST 单段 <Action><Model>、中间件逐路由注册禁 Group(prefix,mw...)、handler 仅返回 (rsp,error)、认证走 header。设计 HTTP API、写路由/handler/中间件时触发。
development
Go 项目结构规范——三层架构(API → Impl → State)、全局状态模式、internal/ 私有包、cmd/ 仅 main.go、go.work 多模块、禁止 Repository 接口和 DI 容器、struct 公共字段开头全 omitempty、handler var rsp 顶声明、禁 legacy migration。设计项目骨架、新建目录、组织包、做架构评审时触发。
development
Go 命名规范——Id/Uid 字段(非 ID)、IsActive/HasMFA 布尔前缀、CreatedAt 时间字段、接收者统一用 p、包名全小写无下划线、泛型类型参数描述性命名、集合字段 xxx_list 禁 xxxs 复数、Enum 0 值 XxxNil 禁 Unknown、禁 Status 统一 State、Set/Update 语义区分。定义结构体字段、函数、变量、包、接收者名、泛型、枚举时触发。