HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
koalaman
shellcheck
Haskell2013–2025
koalaman / shellcheck

shellcheck

ShellCheck, a static analysis tool for shell scripts

92Distinct people
100Mentions
5Explicit recommenders
40.3KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

ShellCheck, a static analysis tool for shell scripts

GitHub

Where it is used

  • GitLab — GitLab uses ShellCheck to lint its shell scripts. It also prescribes a GitLab CI/CD job configuration to run it across projects. Source
  • ShellCheck for Visual Studio Code — ShellCheck for Visual Studio Code bundles the ShellCheck tool and uses it to lint shell scripts, showing ShellCheck warnings in the editor and the Problems view. Source

What people are saying

One of my favorite things about Shellcheck is that the error messages come with a link to a wiki page about the problem. Does anyone know other programs that have a similar…

ufo used a recommendation phrase. 5 indexed comments match. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 10:56:20 AM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year100 dated mentions

Observed mentions: 2013-11-18 12:25:12 UTC to 2025-12-30 22:10:57 UTC.

0510152013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20132014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 6 mentions; 2 submissions, 4 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 8 mentions; 2 submissions, 6 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 9 mentions; 2 submissions, 7 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 10 mentions; 1 submissions, 9 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 6 mentions; 1 submissions, 5 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 13 mentions; 1 submissions, 12 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 13 mentions; 2 submissions, 11 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 15 mentions; 2 submissions, 13 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 9 mentions; 0 submissions, 9 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC202
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC624
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC211
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC826
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC927
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC1019
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC615
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC13112
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC13211
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC15213
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC909
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC404
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC312

What Hacker News says

13 sources
tl;dr - If worried about leaking the path to a secret file, use <() (e.g. <( < "${secret_file_path}")) which makes an opaque ephemeral file i.e. /dev/fdX on the command line (1) Sorry for the top level comment, but I am surprised this hasn't been shared by someone else already. Process substitution(1) (e.g. <(SECRET_STUFF_HERE)) totally solves the problem of leaking secrets to the process table. From RTFA, the author is using "$(< $STEPPATH/certs/root_ca.crt)" and is concerned about leaking "$STEPPATH/certs/root_ca.crt" to the process table. If the Author instead ran <(< $STEPPATH/certs/root_ca.crt) the process table would just have some junk ephemeral file path instead. For example... lets say for an arbitrary example, I didn't want folks knowing from the process table that I was getting the file details of /etc/passwd ### LEAKY ~ %
Read the rest
wc /etc/passwd 110 297 6946 /etc/passwd I could instead use process substitution: % wc <( < /etc/passwd ) 110 297 6946 /dev/fd/11 I have found this to be most useful not for files, but for temporary secret variables that I want to wrap in a file, but not have to deal with the cleanup and management of that file. For a shell variable example, rather than writing "B64 is not encryption" to a file, and then having to cleanup that file... use process substitution to create the temporary file which doesn't leak to the process table. ## Don't do : ~ % echo "B64 is not encryption" | base64 QjY0IGlzIG5vdCBlbmNyeXB0aW9uCg== ## Do this instead; also 'echo' is a bash builtin and won't leak ~ % base64 <(echo "B64 is not encryption") QjY0IGlzIG5vdCBlbmNyeXB0aW9uCg== Or if used in scripting: secret="B64 is not encryption" bar="$(base64 <(echo "${secret}"))" Some caveats: This only works for commands that accept files for arguments. If a command requires a secret to be passed in as a plaintext argument, then maybe the right answer is to rethink using that command in the first place (maybe <<<"HERESTRINGS" (2) helps in that case though I doubt it). PROTIP: And for the love of all that's holy... run shellcheck(3) before considering running your script for realz if you want to keep your butt out of the fire. Also, the google shell style guide (4) is full of practical/good stuff. Shellcheck and the google style guide are pretty magical. I lost 10 lbs without dieting, became more attractive, and married my wife from following the guidance from those two resources. You can too! (caveat lector, ymmv, not legal advice (ianal), wife is already taken... sorry) --- (1) https://www.gnu.org/software/bash/manual/html_node/Process-S... (2) https://en.wikipedia.org/wiki/Here_document#Here_strings (3) https://github.com/koalaman/shellcheck (4) https://google.github.io/styleguide/shellguide.html
In How to handle secrets on the command line
If you use iTerm2 (or I think this feature is available in other terminal software) you can use "Smart Selections" to transform any ShellCheck errors into links to the wiki. 1. Create a Smart Selection with the regular expression "SC\d+" 2. Add an action to "Open URL...", with the URL "https://github.com/koalaman/shellcheck/wiki/\0" (\0 will be replaced with the matched regex) 3. Now holding down the command key will change any ShellCheck errors to be active http links.
In ShellCheck: Finds bugs in your shell scripts
This is really cool and having spoken with the lead dev, Kenneth, I trust that this will continue to be well supported. This is built on tree-sitter, but there are a couple of other interesting shell parser projects: * https://github.com/mvdan/sh * https://github.com/koalaman/shellcheck At Fig (https://withfig.com), we had to write a bash parser from scratch. These projects all work well in the IDE context, but in a repl environment (ie when typing in your terminal) they don't support incomplete commands very well. e.g if I type `echo "$(` the above parsers will break as the double quote and parentheses are not closed.
In Bash-LSP: A language server for Bash
I like the approach that ShellCheck uses for its verbose error messages. Every error message is identified by an easily-googleable error ID that is not translated and there is a link to the shellcheck wiki where you can find an in-depth explanation of the error and possible ways to fix it. For example, a typical run of shellcheck might look something like this: ~/test> shellcheck blah.sh In blah.sh line 2: echo $1 ^-- SC2086: Double quote to prevent globbing and word splitting. Did you mean: echo "$1" For more information: https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ... https://github.com/koalaman/shellcheck/
In Program Eloquence Considered Harmful

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.