Introduction

shellcheck is a tool from shellcheck.net that can be run from the browser or installed to your local machine for checking the syntax of your shell scripts.

Some of the things shellcheck complains about should be ignored but for the most part if you use the following syntax to check a script named FILE, shellcheck is mostly helpful in nature:

shellcheck -s dash -e SC2004,SC2034,SC2166,SC2169 FILE

The -e ... argument is required to disable checks that are not accurate. Below is a discussion about each:

SC2004 checks for $/${} applied to variable names inside arithmetic expressions inside $(( ... )):

shift $(( $OPTIND - 1 ))
          ^-- SC2004: $/${} is unnecessary on arithmetic variables.

In FreeBSD 5.x and newer, this is true and you could use just the variable name. However, if you are targeting FreeBSD 4.x or older you must always use them and as-such can add this check to -e to make shellcheck ignore this situation. Shell code in the FreeBSD base Operating System should use leading dollar signs to make code more portable.

SC2034 checks for unused variables.

pgm="${0##*/}"
^-- SC2034: pgm appears unused. Verify it or export it.

While this can catch real instances of unused variables, it cannot tell if the variable is used in a file that has been included later using the . builtin. Also, do not simply export the variable to get rid of this warning. If your program exports too much information, it may fail to fork external executables (by design). The Operating System commonly places limits on process resources for all users except the root superuser and as-such, export should be used sparingly and only when absolutely necessary to pass the variable to an external executable.

SC2166 warns if you pass more than 4 arguments to the [ builtin or if you use the -a or -o options to the [ builtin:

[ "$SUDO_USER" -a "$DISPLAY" ]
               ^-- SC2166: Prefer [ p ] && [ q ] as [ p -a q ] is not well defined.

It is generally accepted to use the -a and -o options to the [ builtin to combine tests even if not strictly supported by POSIX. The number of shells that do not support this are rare.

SC2169 warns about dash short-comings but can become confused when you use dynamic file descriptor redirection:

echo 123 >&$stderr
         ^-- SC2169: In dash, >& is not supported.

shellcheck is unable to realize that $stderr resolves to a number to invoke the >&n syntax for redirecting to a specific file descriptor. It is complaining here because it thinks you are trying to use a csh feature which allows you to redirect both stdout and stderr to a file by using >& file instead of > file (which in any shell only redirects stdout into file).

Last updated