CLI tool
koalaman/shellcheck avatar
koalaman/shellcheck

ShellCheck: Static Analysis That Treats Shell Scripts as Real Code

ShellCheck, a static analysis tool for shell scripts. From your terminal Run shellcheck yourscript in your terminal for instant output, as seen above.

40,041 stars1,944 forksHaskellGPL-3.0

At a glance

What is it?
ShellCheck is a GPLv3 static analysis tool for bash and sh scripts that catches syntax errors, semantic pitfalls, and portability issues. This review covers its mechanisms, installation paths, limitations, and how it fits into build pipelines.
Who is it for?
Adopt ShellCheck if you write or maintain bash or sh scripts and want immediate, categorized feedback on quoting, conditionals, and portability. Skip it if your scripts are trivial one-liners or if you need deep runtime behavior analysis.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 43 days ago.
What is it written in?
Mainly Haskell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What ShellCheck Solves and Who Needs It

Shell scripts fail in ways that are hard to see by reading. A missing quote turns a variable expansion into a word split. A conditional that looks correct behaves differently under `set -e`. ShellCheck exists to surface these problems before the script runs. It targets three levels of users: beginners who get cryptic errors from the shell, intermediate users who hit semantic surprises, and advanced users who worry about corner cases that break under future changes. The README's stated goals make this three-tier intent explicit. If you write scripts that outlive a single session, or that run unattended in CI, ShellCheck is aimed at you. If you only write throwaway one-liners, the overhead of installing and running a linter may not pay off.

How ShellCheck Works: Parsing and Rule Sets

ShellCheck is written in Haskell, which matters for its behavior. It parses the script into an abstract syntax tree rather than applying regex patterns. This means it understands control flow, variable assignments, and command substitutions as structured data. The tool then applies a set of rules organized by category: quoting, conditionals, frequently misused commands, beginner mistakes, style, data and typing errors, robustness, and portability. The README's gallery of bad code shows these categories in action. Because the parser is real, ShellCheck can detect issues that string matching would miss, such as a variable used before assignment or a `[[` construct that is not POSIX-compatible. The trade-off is that the parser must keep up with shell syntax evolution. The project's release cadence, with v0.11.0 in August 2025, suggests active maintenance, but you cannot assume every new shell feature is covered immediately.

Getting It Running: Commands and Config

The simplest invocation is `shellcheck yourscript`. That prints warnings and suggestions to standard output. For CI, the tool uses canonical exit codes, so a shell command like `shellcheck myscripts/*.sh` in a Makefile will fail the build if any warnings are found. The README shows a Makefile target and a Travis CI script block that both rely on this behavior. Installation is broad. On Debian you run `sudo apt install shellcheck`. On macOS with Homebrew, `brew install shellcheck`. On Windows, `winget install --id koalaman.shellcheck`. There is also a Docker image: `docker run --rm -v "$PWD:/mnt" koalaman/shellcheck:stable myscript`. For version pinning, the README suggests manually installing a specific version to avoid surprise build breaks when new warnings appear. Output formats include plain text, JSON, CheckStyle XML, and GCC-compatible warnings, which are useful for editor integration.

Where ShellCheck Falls Short

ShellCheck is a static analyzer, not a runtime checker. It cannot catch errors that depend on environment state, such as a missing executable at runtime or a variable set by another script. It also has a learning curve for its warning codes. A beginner might see `SC2086` and not know what to do without reading the wiki. The README's gallery helps, but it is not exhaustive. Another limitation is that ShellCheck is opinionated. Its style rules may flag patterns that are intentional, such as using `cat` in a pipeline for readability. You can ignore issues, but the README only points to an "Ignoring issues" section without detailing the syntax in the cleaned material. This means you may need to consult the wiki to suppress false positives. Finally, the tool targets bash and sh. It does not cover zsh or fish. If your team uses those shells, ShellCheck is the wrong tool.

Alternatives: How They Differ in Approach

The main alternative is `bash -n`, the shell's built-in syntax check. It is fast and requires no installation, but it only checks syntax, not semantics. `bash -n` will not warn about unquoted variables or portability issues. ShellCheck goes further by analyzing the AST and applying rules. Another alternative is `shfmt`, a formatter that also parses shell scripts. `shfmt` focuses on consistent formatting, not on warnings. It can normalize indentation and line breaks, but it will not tell you that your `[[` test is not POSIX. If you need both formatting and linting, you can run `shfmt` and ShellCheck together. The difference in approach is clear: `bash -n` is a grammar check, `shfmt` is a style tool, and ShellCheck is a semantic linter. Choose based on what you need to catch.

Maintenance and License Considerations

ShellCheck is licensed under GPL-3.0. That means if you distribute a modified version, you must share the source under the same license. For internal use, this is rarely a concern. The project is actively maintained, with a stable release in August 2025. The README's caution about new warnings breaking builds is a real maintenance cost. Each release can add new checks, and those checks may flag existing scripts. You must budget time to update scripts or add ignore directives when upgrading. The project also relies on a community of contributors, as indicated by the testimonials section, though the cleaned material does not name them. The Haskell codebase means contributors need to know Haskell, which narrows the pool of potential maintainers. For most users, this is irrelevant because you consume the binary, not the source.

Integration and Editor Support

ShellCheck is designed to fit into existing workflows. The README lists editor plugins for Vim, Emacs, Sublime, Pulsar Edit, and VS Code. These plugins typically run ShellCheck on save and display warnings inline. For CI, the tool works with Travis, CircleCI, GitHub Actions (Linux only), and other services. The README also mentions that most services let you install ShellCheck yourself. This flexibility is a strength. The GCC error compatibility mode means editors that understand compiler errors can parse ShellCheck output without a dedicated plugin. The JSON and CheckStyle XML formats are useful for custom reporting. If you want to enforce a specific version in CI, the README suggests pinning, and services like Trunk allow explicit versioning. The practical takeaway is that ShellCheck does not force you into a particular editor or pipeline; it adapts to what you already use.

Editorial conclusion

Adopt ShellCheck if you write or maintain bash or sh scripts and want immediate, categorized feedback on quoting, conditionals, and portability. Skip it if your scripts are trivial one-liners or if you need deep runtime behavior analysis. Before relying on it in CI, pin a specific version, because new releases add warnings that can break builds. Verify that the exit code behavior matches your pipeline expectations, and test a representative set of scripts against the version you plan to use.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Community notes

Community notes