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,334 stars1,975 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 5 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 November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • koalaman/shellcheck40,334 ★ · +555
Star history
Repository2026-07-292026-11-13
koalaman/shellcheck39.8k40.3k

555 Stars in the last 107 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial 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, and the README has an "Ignoring issues" section for that. 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 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.

Frequently asked questions

What is ShellCheck?

ShellCheck is a GPLv3 static analysis tool that gives warnings and suggestions for bash and sh shell scripts. Its goals are to point out beginner syntax issues that cause cryptic shell errors, intermediate semantic problems that make a shell behave strangely, and subtle pitfalls that can break an otherwise working script later. It outputs plain text, JSON, CheckStyle compatible XML or GCC compatible warnings.

how to install shellcheck

The README's answer is your package manager, and it lists Cabal with cabal install ShellCheck into ~/.cabal/bin, Stack with stack install ShellCheck into ~/.local/bin, plus apt, pacman, emerge, dnf, brew, port, pkg_add, zypper, eopkg, conda-forge and snap. It also advises manually installing a specific version so a new release with new warnings cannot break your build.

how to use shellcheck in vscode

The README points to the vscode-shellcheck extension for VSCode. It is one of five named integrations, alongside ALE, Neomake and Syntastic for Vim, Flycheck and Flymake for Emacs, SublimeLinter for Sublime, and linter-shellcheck-pulsar for Pulsar Edit. Most other editors use the GCC error compatibility format documented in the man page.

Is ShellCheck a linter?

It is used as one. The README says ShellCheck is mostly intended for interactive use but can easily be added to builds or test suites, because it makes canonical use of exit codes, so a shellcheck command can be part of the process. The examples given are a Makefile target and a Travis CI script block.

how to install shellcheck in windows

Three routes are listed: chocolatey with choco install shellcheck, winget with winget install --id koalaman.shellcheck, and scoop with scoop install shellcheck. Editors on Windows can also consume the GCC compatible output described in the man page if there is no first class plugin.

how to install shellcheck on mac

On macOS the README lists brew install shellcheck for Homebrew and sudo port install shellcheck for MacPorts. Conda users can install from conda-forge.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/koalaman-shellcheck.svg)](https://hysenlabs.com/projects/koalaman-shellcheck)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/koalaman-shellcheck.svg)](https://hysenlabs.com/projects/koalaman-shellcheck)

Was this useful?