# 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. ## Install Save in your project root: # ShellCheck — Static Analysis for Shell Scripts ## Quick Use ```bash # Install brew install shellcheck # macOS sudo apt install shellcheck # Debian/Ubuntu winget install koalaman.shellcheck # Windows # Lint a script shellcheck deploy.sh # Exit non-zero on any warning (useful in CI) shellcheck --severity=warning deploy.sh ``` ## 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 ```bash # .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 ``` ```yaml # 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 - GitHub: https://github.com/koalaman/shellcheck - Website: https://www.shellcheck.net - License: GPL-3.0 --- Source: https://tokrepo.com/en/workflows/8e8e1dbb-3814-11f1-9bc6-00163e2b0d79 Author: AI Open Source