Validating Syntax for Bash Scripts with ShellCheck


is a GPLv3 tool that gives warnings and suggestions for bash/sh shell scripts:


The goals of ShellCheck are

  • To point out and clarify typical beginner’s syntax issues that cause a shell to give cryptic error messages.
  • To point out and clarify typical intermediate level semantic problems that cause a shell to behave strangely and counter-intuitively.
  • To point out subtle caveats, corner cases and pitfalls that may cause an advanced user’s otherwise working script to fail under future circumstances.

From your terminal

Let us install and validate shellcheck (on macOS)

~  brew install shellcheck                                                                                                                                                             
==> Downloading
Already downloaded: /Users/macpro/Library/Caches/Homebrew/downloads/95affa345c01b7e2e46b5f9fa41e61267e61f01af1ba07385a9de41d1ec519b8--shellcheck-0.8.0.bottle_manifest.json
==> Downloading
Already downloaded: /Users/macpro/Library/Caches/Homebrew/downloads/64bf6d6e544255397ff1cd9bb6eba476c62ebfd7306ec2b0dd26d75319eb0f70--shellcheck--0.8.0.monterey.bottle.tar.gz
==> Pouring shellcheck--0.8.0.monterey.bottle.tar.gz
🍺 /usr/local/Cellar/shellcheck/0.8.0: 7 files, 9.7MB
==> Running `brew cleanup shellcheck`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
~  shellcheck
No files specified.
Usage: shellcheck [OPTIONS...] FILES...
-a --check-sourced Include warnings from sourced files
-C[WHEN] --color[=WHEN] Use color (auto, always, never)
-i CODE1,CODE2.. --include=CODE1,CODE2.. Consider only given types of warnings
-e CODE1,CODE2.. --exclude=CODE1,CODE2.. Exclude types of warnings
-f FORMAT --format=FORMAT Output format (checkstyle, diff, gcc, json, json1, quiet, tty)
--list-optional List checks disabled by default
--norc Don't look for .shellcheckrc files
-o check1,check2.. --enable=check1,check2.. List of optional checks to enable (or 'all')
-P SOURCEPATHS --source-path=SOURCEPATHS Specify path when looking for sourced files ("SCRIPTDIR" for script's dir)
-s SHELLNAME --shell=SHELLNAME Specify dialect (sh, bash, dash, ksh)
-S SEVERITY --severity=SEVERITY Minimum severity of errors to consider (error, warning, info, style)
-V --version Print version information
-W NUM --wiki-link-count=NUM The number of wiki links to show, when applicable
-x --external-sources Allow 'source' outside of FILES
--help Show this usage summary and exit

Run shellcheck yourscript in your terminal for instant output.

In your editor

Please refer to for compatible list of editors.

ShellCheck for Visual Studio Code

Integrates ShellCheck into VS Code, a linter for Shell scripts.

(this “extension”), requires ShellCheck (the awesome static analysis tool for shell scripts) to work.

ShellCheck for VS Code

ShellCheck in Action

Create a simple bash script “” with below code:

#! /bin/bashecho -n “Enter a number: “
read -r NUM
if [[ $NUM -gt 10 ]]
echo “The variable is greater than 10.”
echo “The variable is equal or less than 10.”

Now, let us validate our bash script

~/Documents/scripts/shellcheck  shellcheck                                                                                                                                   ~/Documents/scripts/shellcheck 

ShellCheck returns no syntax errors.

Now, let us remove then from if…then statement in our bash script. It should look like below:

#! /bin/bashecho -n “Enter a number: “
read -r NUM
if [[ $NUM -gt 10 ]]
echo “The variable is greater than 10.”
echo “The variable is equal or less than 10.”

Validate the script now to see if shellcheck can identify the syntax error:

~/Documents/scripts/shellcheck  shellcheck                                                                                                                            In line 6:
if [[ $NUM -gt 10 ]]
^-- SC1049 (error): Did you forget the 'then' for this 'if'?
^-- SC1073 (error): Couldn't parse this if expression. Fix to allow more checks.
In line 8:
^-- SC1050 (error): Expected 'then'.
^-- SC1072 (error): Unexpected keyword/token. Fix any mentioned problems and try again.
For more information:
-- Did you forget the 'then' for thi...
-- Expected 'then'.
-- Unexpected keyword/token. Fix any...

ShellCheck validates the script and clearly outputs that syntax errors.

Test Bash’s noexec mode to see if it can effectively catch syntax errors

First, let us add then back to the script and remove [[ from the script as shown below:

#! /bin/bashecho -n "Enter a number: "
read -r NUM
if $NUM -gt 10 ]]
echo "The variable is greater than 10."
echo "The variable is equal or less than 10."

Now, let us see if noexec can catch the syntax error:

~/Documents/scripts/shellcheck  bash -n                                                                                                                                  ~/Documents/scripts/shellcheck 

noexec couldn’t catch the syntax error.

Now, let us validate the same script with Shellcheck:

~/Documents/scripts/shellcheck  shellcheck                                                                                                                                   In line 6:
if $NUM -gt 10 ]]
^-- SC2171 (warning): Found trailing ]] outside test. Add missing [[ or quote if intentional.
For more information:
-- Found trailing ]] outside test. A...
~/Documents/scripts/shellcheck 

ShellCheck validated the bash script and clearly indicates that [[ are missing.


While ShellCheck is mostly intended for interactive use, it can easily be added to builds or test suites. It makes canonical use of exit codes, so you can just add a shellcheck command as part of the process. We have also seen ShellCheck can catch errors that are missed by noexec. Overall, nice little tool to validate your bash scripts.



Protector of the Cloud. 404 bio not found

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store