Linux Basic — ShellCheck Compliance

1 minute read

ShellCheck Compliance

ShellCheck is the static analyser every shell script should pass. It catches quoting bugs, unset vars, bad globs, and 200+ other issues before runtime.


Install & Run

# macOS
brew install shellcheck

# Ubuntu/Debian
apt install shellcheck

# run on a script
shellcheck script.sh

Common Warnings & Fixes

SC2086: Quote to prevent word splitting

# BAD
echo $var

# GOOD
echo "$var"

Always quote variables unless you explicitly want splitting.


SC2046: Quote to prevent word splitting in $(...)

# BAD
files=$(ls *.txt)

# GOOD
mapfile -t files < <(ls *.txt)
# or just use globs:
files=(*.txt)

SC2155: Declare and assign separately

# BAD — exit code of cmd is lost
local result=$(some_command)

# GOOD
local result
result=$(some_command) || die "command failed"

SC2164: cd can fail — use cd ... || exit

# BAD
cd /some/dir

# GOOD
cd /some/dir || exit 1

Or use set -e so the script exits automatically.


SC2128: Expanding an array without an index

# BAD
files=("a" "b")
echo "$files"        # only prints first element

# GOOD
echo "${files[@]}"   # all elements

Disabling Checks (Rarely Needed)

If ShellCheck flags something intentional, disable it with a comment explaining why:

# shellcheck disable=SC2086
# word-splitting is intentional here for xargs
xargs cmd $opts

Disable per-line, not globally, and always add a reason.


CI Integration

Add to your CI pipeline:

# .github/workflows/lint.yml
- name: ShellCheck
  run: shellcheck **/*.sh

Fail the build on any warning.


Levels of Compliance

Level Description
None no warnings about critical bugs (quoting, unset vars)
Style no style warnings (use [[ over [, etc.)
Pedantic enable all checks including style nitpicks

Aim for zero warnings at default level. Pedantic is optional.


ShellCheck + set -euo pipefail

ShellCheck’s warnings overlap with strict mode. Use both:

set -euo pipefail  # runtime safety
# ShellCheck catches the issues that slip past -e/-u

Next → Practice Exercises

Updated: