Community程式設計與開發github.com

Jamie-BitFlight/bash-lint

當使用者要求「lint bash script」、「run shellcheck」、「format shell script」、「use shfmt」、「fix shellcheck errors」,或提及 shell 腳本 lint、格式化、程式碼品質或 bash 的 pre-commit hooks 時,應使用此技能。

bash-lint 是什麼?

這個技能整合了 ShellCheck 與 shfmt 兩套工具,協助開發者確保 Bash 腳本的品質與一致性。ShellCheck 負責靜態分析,能揪出常見的語法錯誤、潛在漏洞與不符合最佳實踐的寫法;shfmt 則專注於自動格式化,讓團隊的腳本能遵循同一套縮排與排版規範。該技能支援多種平台與環境,包括本地端安裝、VS Code 與 Vim 等編輯器整合、pre-commit 鉤子設定,以及 GitHub Actions 與 GitLab CI 等 CI/CD 流程。技能內容涵蓋 ShellCheck 的安裝、常用規則碼與排除指令、shfmt 的格式化選項與 .editorconfig 配置、pre-commit 的 YAML 設定範例,以及常見問題(如 SC2086 引用未加雙引號、SC2155 宣告與賦值分離)的修復方式,讓開發者能快速上手並建立自動化的腳本品質把關流程。

相容平台~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 腳本 Lint

整合 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   # 統一 diff

常用 ShellCheck 規則碼

規則碼問題描述修正方式
SC2086雙引號,避免因 glob/splitting 導致問題"$var"
SC2046命令替換請加上引號"$(cmd)"
SC2006使用 $() 代替反引號$(cmd)
SC2034變數似乎未使用移除或匯出
SC2155應分開宣告與賦值拆成 local var; var=$(...)
SC2164使用 cd ... || exit處理 cd 失敗
SC2181直接檢查指令的退出狀態if cmd; then
SC2129考慮將多個寫入動作合併使用 { } > file
SC1090無法追蹤來源檔使用 # 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

基本用法

# 格式化並輸出到 stdout
shfmt script.sh

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

# 檢查格式(若未格式化則 exit 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 case 縮排
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"]

  # 替代方案:本機 hooks
  - 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

# 安裝 hooks
pre-commit install       # 或使用:prek install

# 對所有檔案執行
pre-commit run --all-files       # 或使用:prek run --all-files

# 執行特定 hook
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:加上引號避免 splitting

# 錯誤
echo $var

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

SC2155:分開宣告與賦值

# 錯誤 ─ 會遮蓋 exit status
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:來源檔案問題

# 對動態來源加上指令
# 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).

相關技能