Scripts You Can Trust

Fail loudly and clearly, clean up after yourself, find bugs, and prove a script works.

Updated

Failing Well

  1. Errors a User Can Act On (Journeyman): A script people depend on says what went wrong and what to do about it: it prints problems on standard error with >&2, stops with an exit code that means something (0 it worked, 1 it failed, 2 it was run wrong), and keeps those habits in a die function and a usage message.
  2. Strict Mode: set -euo pipefail (Freelancer): set -euo pipefail makes a script stop at the first sign of trouble: -e stops at a command that fails, -u at a variable that was never set, and -o pipefail at a pipeline with a failing part, with a few surprises to know about: a grep that finds nothing, ((count++)) and a missing $1.
  3. Cleaning Up: trap and mktemp (Freelancer): mktemp makes a temporary file or folder with a name no other file has, and trap '...' EXIT runs cleanup however a script ends, Ctrl+C included, so a script that works in a scratch file never leaves half-finished work behind.

Finding Bugs

  1. Debugging Scripts: bash -x (Journeyman): bash -x runs a script and prints every line before it runs, with its variables already filled in, so you can watch what the script really did; set -x and set +x trace one part only, and PS4 adds line numbers to the trace.
  2. ShellCheck: A Second Pair of Eyes (Journeyman): ShellCheck reads a script without running it and points out likely mistakes, each with its line, a code such as SC2086 and a plain message; the codes worth knowing are an unquoted variable, a cd that might fail and a loop over ls, and a disable comment silences one warning on purpose.
  3. Testing Scripts with bats (Freelancer): A test is a small script that runs yours and checks the result; bats runs a file of them, each written with @test, run and checks on $status and $output, in a fresh folder from setup, and reports each one as passed or failed, with the line that failed.

Exercise: Make It Fail Well

  1. Exercise: Make It Fail Well (Journeyman): Turn a photo mover that works only on a good day into one you can trust: strict mode, a die function, a usage message, errors on standard error, exit codes that mean something, cleanup with trap, a bug found with bash -x, and two bats tests of your own, while a check script runs it job by job.