Automation projects

Test and review the script

Run syntax checks, ShellCheck, failure cases, clean-environment tests, and a documented cleanup path.

10 minute lesson

~~~

A script is a program. It needs tests for inputs, failures, side effects, and the environment it assumes. Most shell scripts get none of that: they run once on the author’s machine on a good day, then get trusted for years. This review pass closes the course projects.

Run static checks

bash -n script.sh
shellcheck script.sh
env -i PATH=/usr/bin:/bin bash script.sh

bash -n parses the script without running it — a pure syntax check that catches an unclosed if before anything executes.

ShellCheck is the linter for shell. It knows every classic from this course: unquoted expansions, read without -r, parsing ls. Each finding has a code you can look up:

shellcheck backup.sh
# In backup.sh line 12:
# tar -czf $archive -C $source_directory .
#          ^------^ SC2086: Double quote to prevent globbing and word splitting.

The third command is the environment test. env -i starts from an empty environment and hands the script only a minimal PATH. A script that works in your terminal but depends on your aliases, your PATH additions, or a variable you exported months ago fails here — exactly the way it will fail under cron at 03:00.

Exercise real failures

Static checks can’t see behavior. Add a test directory with disposable fixtures and run the script against trouble: missing commands, interrupted work (Ctrl-C mid-run), weird filenames like 'has space.txt' and -dash.txt, and repeated execution — a second run must not corrupt what the first produced.

For each case, check the three things every caller sees: exit status, standard error, and side effects on disk. A failure that exits zero is a bug. So is a success that leaves temporary files behind — the cleanup path deserves a test of its own.

Warnings are a conversation

Static analysis is guidance, not proof. Sometimes ShellCheck flags something you did on purpose, like an intentional word split. Understand a warning before suppressing it, and document deliberate exceptions:

# shellcheck disable=SC2086  # $TAR_FLAGS is intentionally split into words
tar $TAR_FLAGS -czf "$archive" .

A disabled check with a comment is a recorded decision. A disabled check without one is a future bug report with your name on it.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →