Community编程与开发github.com

Jamie-BitFlight/bash-lint

当用户请求“lint bash 脚本”、“运行 shellcheck”、“格式化 shell 脚本”、“使用 shfmt”、“修复 shellcheck 错误”或提及 shell 脚本 linting、格式化、代码质量或 bash 的 pre-commit 钩子时,应使用此技能。

bash-lint 是什么?

此技能为 bash 脚本提供全面的代码质量保证,集成 shellcheck(静态分析)和 shfmt(格式化)。它帮助开发者自动检测常见问题,例如未引用的变量、未使用的变量和不当的退出状态检查,同时确保一致的代码风格。该技能支持多种平台,包括 Linux、macOS 和 Windows(通过 WSL),并提供了在本地、pre-commit 钩子和 CI/CD 系统(如 GitHub Actions 和 GitLab CI)中的详细配置说明。它涵盖了 shellcheck 指令、常用错误代码及修复方法、shfmt 格式化选项、以及编辑器(VS Code、Vim)集成示例。通过使用此技能,开发者可以显著提高 bash 脚本的可靠性、可维护性和安全性。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Jamie-BitFlight/claude_skills/tree/main/plugins/bash-development/skills/bash-lint

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Bash 代码检查(Linting)

集成 Shellcheck 和 shfmt,用于保证 bash 脚本质量。

Shellcheck

安装

# Debian/Ubuntu
apt install shellcheck

# macOS
brew install shellcheck

# 从源码安装
cabal update && cabal install ShellCheck

基本用法

# 检查单个文件
shellcheck script.sh

# 检查多个文件
shellcheck *.sh

# 指定 shell 方言
shellcheck --shell=bash script.sh
shellcheck --shell=sh script.sh

# 排除特定规则
shellcheck --exclude=SC2086 script.sh
shellcheck --exclude=SC2086,SC2046 script.sh

# 输出格式
shellcheck --format=gcc script.sh    # GCC 风格
shellcheck --format=json script.sh   # JSON 格式(适合工具链)
shellcheck --format=diff script.sh   # 统一差异格式

常见 Shellcheck 错误码

代码问题修复
SC2086缺少双引号,可能导致通配符/分词错误"$var"
SC2046命令替换需要使用引号"$(cmd)"
SC2006请使用 $() 代替反引号$(cmd)
SC2034变量似乎未使用删除或导出
SC2155应分开声明和赋值拆分为 local var; var=$(...)
SC2164使用 `cd ...
SC2181直接检查命令退出状态if cmd; then
SC2129考虑将写入操作分组使用 { } > file
SC1090无法跟踪被 source 的文件使用 # shellcheck source=路径
SC2154引用了未赋值的变量初始化或声明

Shellcheck 指令

# 禁用下一行检查
# shellcheck disable=SC2086
echo $unquoted_var

# 禁用整个文件的检查(放在文件顶部)
# shellcheck disable=SC2086,SC2046

# 为 source 命令指定源文件
# shellcheck source=./lib/functions.sh
source "$SCRIPT_DIR/lib/functions.sh"

# 指定 shell 方言
# shellcheck shell=bash

# 禁用块的检查(不支持 - 请使用逐行禁用)

行内指令模式

# 禁用特定警告并附上说明
# shellcheck disable=SC2034 # 该变量由 source 脚本使用
readonly CONFIG_VERSION="1.0"

# 禁用多个错误码
# shellcheck disable=SC2086,SC2046
result=$(echo $var)

# 动态路径的 source 指令
# shellcheck source=/dev/null
source "${DYNAMIC_PATH}/config.sh"

shfmt

安装

# macOS
brew install shfmt

# Go 安装
go install mvdan.cc/sh/v3/cmd/shfmt@latest

# Snap
snap install shfmt

# 二进制下载
# 来自 https://github.com/mvdan/sh/releases

基本用法

# 格式化并输出到标准输出
shfmt script.sh

# 原地格式化文件
shfmt -w script.sh

# 检查格式(如果未格式化则退出码为 1)
shfmt -d script.sh

# 递归处理目录
shfmt -w .
shfmt -w scripts/

格式化选项

# 缩进
shfmt -i 2 script.sh  # 2 空格缩进
shfmt -i 4 script.sh  # 4 空格缩进
shfmt -i 0 script.sh  # 制表符(默认)

# 二元运算符放在行首
shfmt -bn script.sh

# switch 分支缩进
shfmt -ci script.sh

# 重定向运算符后跟空格
shfmt -sr script.sh

# 保留列对齐填充
shfmt -kp script.sh

# 函数左大括号另起一行
shfmt -fn script.sh

# 组合使用
shfmt -i 4 -ci -bn script.sh

配置 (.editorconfig)

# .editorconfig
[*.sh]
indent_style = space
indent_size = 4
shell_variant = bash
binary_next_line = true
switch_case_indent = true
space_redirects = true

示例转换

使用 shfmt 前:

if [ -f "$file" ];then
echo "exists"
fi

for i in 1 2 3;do
    process $i
done

使用 shfmt -i 4 -ci 后:

if [ -f "$file" ]; then
    echo "exists"
fi

for i in 1 2 3; do
    process $i
done

Pre-commit 集成

.pre-commit-config.yaml

repos:
  - repo: https://github.com/koalaman/shellcheck-precommit
    rev: v0.9.0
    hooks:
      - id: shellcheck
        args: ["--severity=warning"]

  - repo: https://github.com/scop/pre-commit-shfmt
    rev: v3.7.0-1
    hooks:
      - id: shfmt
        args: ["-i", "4", "-ci", "-w"]

  # 替代方案:本地钩子
  - repo: local
    hooks:
      - id: shellcheck
        name: shellcheck
        entry: shellcheck
        language: system
        types: [shell]
        args: ["--severity=warning", "-x"]

      - id: shfmt
        name: shfmt
        entry: shfmt
        language: system
        types: [shell]
        args: ["-i", "4", "-ci", "-w"]

运行 Pre-commit

# 安装钩子
pre-commit install       # 或:prek install

# 在所有文件上运行
pre-commit run --all-files       # 或:prek run --all-files

# 运行特定钩子
pre-commit run shellcheck --all-files
pre-commit run shfmt --all-files

# 在特定文件上运行
pre-commit run --files script.sh

集成到 CI/CD

GitHub Actions

name: Shell Lint

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 运行 ShellCheck
        uses: ludeeus/action-shellcheck@master
        with:
          severity: warning

      - name: 使用 shfmt 检查格式
        uses: mvdan/github-action-shfmt@master
        with:
          flags: -d -i 4 -ci

GitLab CI

shellcheck:
  image: koalaman/shellcheck-alpine:stable
  script:
    - find . -name "*.sh" -exec shellcheck {} +

shfmt:
  image: mvdan/shfmt:latest
  script:
    - shfmt -d -i 4 -ci .

修复常见问题

SC2086:使用引号防止分词

# 错误
echo $var

# 正确
echo "$var"
printf '%s\n' "$var"

SC2155:分开声明和赋值

# 错误 - 隐藏了退出状态
local var=$(some_command)

# 正确
local var
var=$(some_command)

SC2164:使用 cd || exit

# 错误
cd "$dir"
rm -rf *

# 正确
cd "$dir" || exit 1
rm -rf *

# 或者使用子 shell
(cd "$dir" && rm -rf *)

SC2181:直接检查退出状态

# 错误
command
if [ $? -eq 0 ]; then

# 正确
if command; then

SC1090/SC1091:Source 问题

# 为动态 source 添加指令
# shellcheck source=/dev/null
source "$DYNAMIC_PATH/lib.sh"

# 或者指定实际路径
# shellcheck source=./lib/functions.sh
source "$SCRIPT_DIR/lib/functions.sh"

编辑器集成

VS Code

安装 Timon Wong 开发的 "ShellCheck" 扩展。

// settings.json
{
    "shellcheck.enable": true,
    "shellcheck.run": "onSave",
    "shellcheck.executablePath": "shellcheck",
    "editor.formatOnSave": true,
    "[shellscript]": {
        "editor.defaultFormatter": "foxundermoon.shell-format"
    }
}

Vim/Neovim

" 使用 ALE
let g:ale_linters = {'sh': ['shellcheck']}
let g:ale_fixers = {'sh': ['shfmt']}
let g:ale_sh_shfmt_options = '-i 4 -ci'

" 使用 coc.nvim
" 安装 coc-sh 扩展

最佳实践

  1. 尽早运行 shellcheck - 集成到编辑器和 CI 中
  2. 修复问题,不要抑制警告 - 仅在充分理由下才禁用
  3. 记录抑制原因 - 解释为什么禁用规则
  4. 使用严重级别 - CI 中使用 --severity=warning
  5. 保持一致的格式 - 在 pre-commit 中使用 shfmt
  6. 锁定工具版本 - 在 CI/pre-commit 中固定版本

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

Jamie-BitFlight/agentskill-kaizen-meta-docs

Agentskill kaizen plugin documentation index. Load when needing to read about cross-platform notes, improvement plans, or DuckDB integration.

Jamie-BitFlight/bash-51-features

Bash 5.1 release features and improvements with practical examples. Use when working with Bash 5.1 features, epoch time variables, redirection enhancements, or when user asks about Bash 5.1 changes, new features, or version-specific capabilities.

Jamie-BitFlight/bash-52-features

Bash 5.2 release features and improvements with practical examples. Use when working with Bash 5.2 features, variable handling enhancements, readline improvements, or when user asks about Bash 5.2 changes, new features, or version-specific capabilities.

Jamie-BitFlight/bash-53-features

Bash 5.3 release features and improvements with practical examples. Use when working with Bash 5.3 features, new command substitution, GLOBSORT, loadable builtins, or when user asks about Bash 5.3 changes, new features, or version-specific capabilities.

Jamie-BitFlight/bash-development

This skill should be used when the user asks to "write a bash script", "create a shell script", "implement bash function", "parse arguments in bash", "handle errors in bash", or mentions bash development, shell scripting, script templates, or modern bash patterns.

Jamie-BitFlight/bash-logging

This skill should be used when the user asks to "add logging to bash script", "colorize output", "implement log levels", "CI/CD sections", "terminal colors in bash", or mentions logging functions, emoji output, collapsible CI sections, or shlocksmith.

Jamie-BitFlight/bash-portability

This skill should be used when the user asks about "POSIX compatibility", "portable shell scripts", "cross-shell compatibility", "bashisms", "shebang selection", or mentions writing scripts that work on different shells (bash, sh, dash, zsh) or different systems.

Jamie-BitFlight/bash-testing

This skill should be used when the user asks to "test bash script", "write shell tests", "use shunit2", "use shellspec", "create test suite for bash", or mentions unit testing, test frameworks, mocking, or test-driven development for shell scripts.

Jamie-BitFlight/brainstorming-skill

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or when users request help with ideation, marketing, and strategic planning. Explores user intent, requirements, and design before implementation using research-validated prompt patterns.

Jamie-BitFlight/clang-format

Configure clang-format code formatting. Use when: user mentions clang-format or .clang-format, analyzing code style/patterns, creating/modifying formatting config, troubleshooting formatting, brace styles/indentation/spacing/alignment/pointer alignment, or codifying conventions.

Jamie-BitFlight/commitlint

When setting up commit message validation for a project. When project has commitlint.config.js or .commitlintrc files. When configuring CI/CD to enforce commit format. When extracting commit rules for LLM prompt generation. When debugging commit message rejection errors.

Jamie-BitFlight/conventional-commits

When writing a git commit message. When task completes and changes need committing. When project uses semantic-release, commitizen, git-cliff. When choosing between feat/fix/chore/docs types. When indicating breaking changes. When generating changelogs from commit history.

Jamie-BitFlight/dasel-reference

Use when querying, modifying, or converting JSON, YAML, TOML, XML, CSV, HCL, or INI with dasel v3. Complete reference for selectors, functions, conditionals, variables, spread operator, type casting, and format-specific patterns.

Jamie-BitFlight/data-exploration

Use when exploring unknown structured data files with dasel v3 — discover schema, list keys, find nested values, sample arrays, identify data types across JSON, YAML, TOML, XML, CSV, HCL, INI formats

Jamie-BitFlight/data-transformation

Use when modifying, converting, or transforming structured data with dasel v3 — in-place mutations, format conversion, batch operations, array manipulation, object construction, and merge patterns across JSON, YAML, TOML, XML, CSV, HCL, INI

Jamie-BitFlight/delegate

Decompose substantive work into phases, dispatch each phase to a sub-agent, and adjudicate what comes back. Use whenever a request asks for implementation, investigation, a fix, a review, or any change to files — including small ones — and whenever you are about to read source or run a diagnostic yourself instead of handing it off. Also use when a report from a sub-agent needs judging, when a phase needs re-dispatching, or when a user names one instance of a pattern. Does not apply when your own prompt begins "Your ROLE_TYPE is sub-agent." — then follow references/sub-agent-contract.md instead.

Jamie-BitFlight/enterprise-hibernate-hbm

Dasel v3 query patterns for Hibernate .hbm.xml mapping files — entity-table binding, Java property-to-column extraction, one-to-many set/list/bag relationship tracing, many-to-one foreign key discovery, batch scanning across 60+ HBM files. Use when querying Hibernate ORM class mappings, extracting schema metadata from Java persistence layer, or auditing entity-column relationships in enterprise legacy codebases.

Jamie-BitFlight/enterprise-installanywhere

Dasel v3 query patterns for InstallAnywhere .iap_xml installer definitions — use when querying action sequences, discovering variables, resolving platform conditions, navigating panels, or comparing installer variants. Files are 2.5+ MB, 65,000+ lines — too large for context reads, requires structural dasel queries.

Jamie-BitFlight/enterprise-maven-pom

Dasel v3 selector patterns for Maven POM XML files — use when querying dependency versions, filtering by groupId or scope, extracting module hierarchy from parent POMs, or detecting version conflicts across enterprise multi-module Java projects. Load this skill when working with pom.xml files using dasel.

Jamie-BitFlight/enterprise-spring-xml

Dasel v3 selectors for Spring bean factory XML — use when querying any Spring ApplicationContext XML for bean discovery, dependency wiring, JMS destination mapping, property injection extraction, or cross-bean reference tracing. Load this skill before writing dasel selectors against Spring bean XML files (applicationContext.xml, *_beans.xml, spring-*.xml).

相关技能