ConfigsApr 14, 2026·3 min read

ShellCheck — A Static Analysis Tool for Shell Scripts That Finds Bugs Before You Ship

ShellCheck is the linter every shell script author needs. It catches unquoted variables, missing error handling, portability issues, and the hundred other ways bash can silently destroy your weekend.

Introduction

ShellCheck, by Vidar Holen, is the bash linter everyone should run. It catches the quiet killers: unquoted variables that break on filenames with spaces, rm -rf "" disasters from typo'd variables, subshell scoping bugs, portability issues between bash/sh/ash/dash, and dozens more categories of ambiguity that only show up on edge-case inputs.

With over 39,000 GitHub stars, ShellCheck is baked into VS Code, vim/Neovim, CI pipelines everywhere, and https://shellcheck.net. Running it on every script before committing is one of the highest-ROI habits a developer can adopt.

What ShellCheck Does

ShellCheck parses your script with a full shell AST, runs dozens of rule checks (SC1xxx/SC2xxx/SC3xxx codes), and prints warnings with explanations plus links to the wiki. Run it from CLI, an editor plugin, CI, or the web version. Output is also JSON, GCC-style, checkstyle — easy to integrate anywhere.

Architecture Overview

script.sh
    |
[ShellCheck parser (Haskell)]
   Full bash/POSIX AST
    |
[Rule engine]
   200+ rules organized by code
   SC1xxx: parse errors
   SC2xxx: common mistakes
   SC3xxx: POSIX portability
    |
[Output]
   TTY (colored, default)
   JSON, checkstyle, gcc, quiet, diff
    |
[Editor / CI integrations]
   VS Code, Neovim, Sublime, Atom,
   GitHub Actions, GitLab CI,
   pre-commit, reviewdog

Self-Hosting & Configuration

# .shellcheckrc at project root
external-sources=true          # follow `source` directives
source-path=SCRIPTDIR          # resolve relative to script
enable=all
disable=SC1091                 # do not complain about unresolved sources
shell=bash                     # default dialect

# Inline directives
# shellcheck disable=SC2016
echo "Literal \$HOME here"

# shellcheck source=./lib/common.sh
source ./lib/common.sh
# GitHub Actions: fail PR if shell scripts have issues
name: shellcheck
on: [pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ludeeus/action-shellcheck@master
        with:
          severity: warning
          format: gcc

Key Features

  • 200+ rules — parse errors, quoting, portability, subshell gotchas, security
  • Multi-dialect — bash, ksh, dash, sh (POSIX), default configurable
  • Explain + fix — each warning links to the wiki with examples and fixes
  • Editor integrations — VS Code, vim, Neovim, Sublime, Atom, JetBrains
  • CI-ready — GCC-style or JSON output, standard exit codes
  • .shellcheckrc — project-level config for rules + source resolution
  • Inline disables# shellcheck disable=SCxxxx for specific lines
  • Offline + deterministic — no network, reproducible output

Comparison with Similar Tools

Feature ShellCheck shfmt bashate bash -n checkbashisms
Detects bugs Yes (200+) No (formatter) Limited Parse-only POSIX-only
Formats No (use shfmt) Yes No No No
Multi-dialect Yes Yes bash-focused Yes (via -n) sh/dash focus
CI integrations Many Many Limited Universal Limited
Best For Catching bugs Formatting Openstack style Syntax check POSIX portability

FAQ

Q: Do I run shellcheck on every script? A: Yes — make it a pre-commit hook and a CI check. The ROI is enormous; most shell-script production incidents are caused by something ShellCheck would have caught.

Q: How do I suppress a specific warning? A: Use # shellcheck disable=SCxxxx above the offending line. Always add a comment explaining why; otherwise future you will be confused.

Q: ShellCheck vs shfmt? A: Complementary. ShellCheck finds bugs; shfmt formats code. Run both in CI — shfmt first (formatting can't fail), then ShellCheck.

Q: Can ShellCheck auto-fix issues? A: Partially (with --format=diff and --extended-analysis). Most fixes require human judgment (is this variable ever empty? is this expansion safe?).

Sources

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets