How to write better scripts


Writing High-Quality Bash Scripts

Here's what separates solid bash scripts from fragile ones:


Always Start with a Strict Header

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
  • set -e — exit immediately on error

  • set -u — treat unset variables as errors

  • set -o pipefail — catch errors in pipelines (e.g., cmd1 | cmd2)

  • IFS=$'\n\t' — safer word splitting (avoids space-splitting bugs)


Quote Everything

Unquoted variables are a common source of bugs:

# Bad
cp $file $destination

# Good
cp "$file" "$destination"

This matters when filenames contain spaces or special characters.


Use Functions

Break logic into named functions. It makes scripts readable and testable:


Handle Errors Explicitly

Don't rely solely on set -e. Check critical commands:

Print errors to stderr (>&2), not stdout.


Use trap for Cleanup

This ensures temp files are removed even if the script crashes.


Validate Inputs Early


Use [[ ]] Instead of [ ]

[[ ]] is the modern bash conditional — it handles edge cases better:


Prefer $(...) Over Backticks


Name Variables Clearly

Use UPPER_CASE for exported/global variables and lower_case for locals.


Add a Usage/Help Function


Use local in Functions

Without local, variables leak into global scope.


Lint Your Scripts

Use ShellCheckarrow-up-right — it catches an enormous range of bugs:

It's available in most package managers (apt install shellcheck, brew install shellcheck) and has VS Code/Vim/Emacs plugins.


Putting It Together — A Template


The single biggest improvement you can make is running ShellCheck on everything you write. It'll teach you more than almost anything else.


Last updated