Agent skill

bash-lint

This skill should be used when the user asks to "lint bash script", "run shellcheck", "format shell script", "use shfmt", "fix shellcheck errors", or mentions shell script linting, formatting, code quality, or pre-commit hooks for bash.

Stars 33
Forks 4

Install this agent skill to your Project

npx add-skill https://github.com/Jamie-BitFlight/claude_skills/tree/main/plugins/bash-development/skills/bash-lint

SKILL.md

Bash Linting

Shellcheck and shfmt integration for bash script quality assurance.

Shellcheck

Installation

bash
# Debian/Ubuntu
apt install shellcheck

# macOS
brew install shellcheck

# From source
cabal update && cabal install ShellCheck

Basic Usage

bash
# Check single file
shellcheck script.sh

# Check multiple files
shellcheck *.sh

# With specific shell dialect
shellcheck --shell=bash script.sh
shellcheck --shell=sh script.sh

# Exclude specific rules
shellcheck --exclude=SC2086 script.sh
shellcheck --exclude=SC2086,SC2046 script.sh

# Output formats
shellcheck --format=gcc script.sh    # GCC-style
shellcheck --format=json script.sh   # JSON for tooling
shellcheck --format=diff script.sh   # Unified diff

Common Shellcheck Codes

Code Issue Fix
SC2086 Double quote to prevent globbing/splitting "$var"
SC2046 Quote command substitution "$(cmd)"
SC2006 Use $() instead of backticks $(cmd)
SC2034 Variable appears unused Remove or export
SC2155 Declare and assign separately Split local var; var=$(...)
SC2164 Use cd ... || exit Handle cd failure
SC2181 Check exit status directly if cmd; then
SC2129 Consider grouping writes Use { } > file
SC1090 Can't follow sourced file Use # shellcheck source=path
SC2154 Variable referenced but not assigned Initialize or declare

Shellcheck Directives

bash
# Disable for next line
# shellcheck disable=SC2086
echo $unquoted_var

# Disable for entire file (at top)
# shellcheck disable=SC2086,SC2046

# Specify source file for sourcing
# shellcheck source=./lib/functions.sh
source "$SCRIPT_DIR/lib/functions.sh"

# Specify shell dialect
# shellcheck shell=bash

# Disable for block (not supported - use per-line)

Inline Directive Patterns

bash
# Disable specific warning with explanation
# shellcheck disable=SC2034 # Variable used by sourcing script
readonly CONFIG_VERSION="1.0"

# Disable multiple codes
# shellcheck disable=SC2086,SC2046
result=$(echo $var)

# Source directive for dynamic paths
# shellcheck source=/dev/null
source "${DYNAMIC_PATH}/config.sh"

shfmt

Installation

bash
# macOS
brew install shfmt

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

# Snap
snap install shfmt

# Binary download
# From https://github.com/mvdan/sh/releases

Basic Usage

bash
# Format and print to stdout
shfmt script.sh

# Format in place
shfmt -w script.sh

# Check formatting (exit 1 if unformatted)
shfmt -d script.sh

# Recursive directory
shfmt -w .
shfmt -w scripts/

Formatting Options

bash
# Indentation
shfmt -i 2 script.sh  # 2-space indent
shfmt -i 4 script.sh  # 4-space indent
shfmt -i 0 script.sh  # tabs (default)

# Binary operators at start of line
shfmt -bn script.sh

# Switch cases indented
shfmt -ci script.sh

# Redirect operators followed by space
shfmt -sr script.sh

# Keep column alignment paddings
shfmt -kp script.sh

# Function opening brace on separate line
shfmt -fn script.sh

# Combined
shfmt -i 4 -ci -bn script.sh

Configuration (.editorconfig)

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

Example Transformations

Before shfmt:

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

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

After shfmt -i 4 -ci:

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

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

Pre-commit Integration

.pre-commit-config.yaml

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"]

  # Alternative: local 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"]

Running Pre-commit

bash
# Install hooks
pre-commit install

# Run on all files
pre-commit run --all-files

# Run specific hook
pre-commit run shellcheck --all-files
pre-commit run shfmt --all-files

# Run on specific files
pre-commit run --files script.sh

Integration with CI/CD

GitHub Actions

yaml
name: Shell Lint

on: [push, pull_request]

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

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

      - name: Check formatting with shfmt
        uses: mvdan/github-action-shfmt@master
        with:
          flags: -d -i 4 -ci

GitLab CI

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

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

Fixing Common Issues

SC2086: Quote to prevent splitting

bash
# Bad
echo $var

# Good
echo "$var"
printf '%s\n' "$var"

SC2155: Declare and assign separately

bash
# Bad - masks exit status
local var=$(some_command)

# Good
local var
var=$(some_command)

SC2164: Use cd || exit

bash
# Bad
cd "$dir"
rm -rf *

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

# Or with subshell
(cd "$dir" && rm -rf *)

SC2181: Check exit directly

bash
# Bad
command
if [ $? -eq 0 ]; then

# Good
if command; then

SC1090/SC1091: Source issues

bash
# Add directive for dynamic source
# shellcheck source=/dev/null
source "$DYNAMIC_PATH/lib.sh"

# Or specify actual path
# shellcheck source=./lib/functions.sh
source "$SCRIPT_DIR/lib/functions.sh"

Editor Integration

VS Code

Install "ShellCheck" extension by Timon Wong.

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

Vim/Neovim

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

" With coc.nvim
" Install coc-sh extension

Best Practices

  1. Run shellcheck early - integrate into editor and CI
  2. Fix issues, don't suppress - only disable with good reason
  3. Document suppressions - explain why rule is disabled
  4. Use severity levels - --severity=warning for CI
  5. Consistent formatting - use shfmt in pre-commit
  6. Version lock tools - pin versions in CI/pre-commit

Expand your agent's capabilities with these related and highly-rated skills.

Jamie-BitFlight/claude_skills

ccc

This skill should be used when code search is needed (whether explicitly requested or as part of completing a task), when indexing the codebase after changes, or when the user asks about ccc, cocoindex-code, or the codebase index. Trigger phrases include 'search the codebase', 'find code related to', 'update the index', 'ccc', 'cocoindex-code'.

33 4
Explore
Jamie-BitFlight/claude_skills

agent-browser

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction.

33 4
Explore
Jamie-BitFlight/claude_skills

delegate

Quick delegation template for sub-agent prompts. Use when assigning work to a sub-agent, before invoking the Agent tool, or when preparing prompts for specialized agents. Provides the WHERE-WHAT-WHY framework. For comprehensive delegation guidance, activate the agent-orchestration how-to-delegate skill.

33 4
Explore
Jamie-BitFlight/claude_skills

swarm-spawning

Spawn agents and teammates in Claude Code swarms. Use when choosing between subagents vs teammates, selecting agent types (Explore, Plan, general-purpose, plugin agents), configuring spawn backends (in-process, tmux, iterm2), or setting environment variables for spawned agents.

33 4
Explore
Jamie-BitFlight/claude_skills

knowledge-explorer

Manage the research/ knowledge base (KB) of tool and library research entries. Use when browsing KB topics, adding new research entries, updating existing entries with dated revisions, fetching GitHub repo metadata into a draft KB entry, or migrating old-format entries to skill-spec frontmatter. Triggers on tasks like "what do we have on X", "add this to the KB", "update the KB entry for Y", "fetch github info for owner/repo", or "migrate old entries".

33 4
Explore
Jamie-BitFlight/claude_skills

design-anti-patterns

Enforce anti-AI UI design rules based on the Uncodixfy methodology. Use when generating HTML, CSS, React, Vue, Svelte, or any frontend UI code. Prevents "Codex UI" — the generic AI aesthetic of soft gradients, floating panels, oversized rounded corners, glassmorphism, hero sections in dashboards, and decorative copy. Applies constraints from Linear/Raycast/Stripe/GitHub design philosophy: functional, honest, human-designed interfaces. Triggers on: UI generation, dashboard building, frontend component creation, CSS styling, landing page design, or any task producing visual interface code.

33 4
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results