# Introduction

shellcheck is a tool from [shellcheck.net](https://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).
