Section 1: Foundations of reliable scripts
Anatomy of a good script
Let us start with a small script and improve it until it is something you would trust on a server.
#!/usr/bin/env bash
set -euo pipefail
readonly SRC_DIR="${1:?usage: $0 SRC_DIR DEST_DIR}"
readonly DEST_DIR="${2:?usage: $0 SRC_DIR DEST_DIR}"
readonly STAMP="$(date +%Y-%m-%d_%H%M%S)"
main() {
mkdir -p -- "$DEST_DIR"
tar -czf "$DEST_DIR/backup_$STAMP.tar.gz" -C "$SRC_DIR" .
echo "Created $DEST_DIR/backup_$STAMP.tar.gz"
}
main "$@"
Line by line
#!/usr/bin/env bashis the shebang. It tells the system to run the file with Bash found on the PATH. Do not use#!/bin/shif you use Bash features; on Debian and Ubuntushis dash, a different shell.set -euo pipefailenables what people call strict mode: exit on errors, treat unset variables as errors, and make a pipeline fail if any command in it fails. It catches many bugs early, but it has surprising corners, which we explore in lesson four.${1:?message}stops the script with a message if the first argument is missing or empty.readonlyprevents accidental reassignment.- Every variable expansion is in double quotes. This is the single most important habit in Bash.
--aftermkdir -pmarks the end of options, so a directory name starting with a dash is not mistaken for an option.- Wrapping the logic in
mainand callingmain "$@"at the end keeps the script readable and ensures Bash has parsed the entire file before anything runs.
Make it executable and run it
chmod +x backup.sh
./backup.sh ~/projects /tmp/backups
echo $?
$? holds the exit status of the last command. Zero means success; anything else means failure. Every script you write should exit non zero when it fails, so callers such as cron, CI or other scripts can react.
Install ShellCheck now
sudo apt install shellcheck # or: brew install shellcheck
shellcheck backup.sh
ShellCheck is a static analyser that finds quoting mistakes, unused variables and dozens of subtle bugs. Run it on every script from today. It explains each warning with a code you can look up, and you will learn Bash faster by reading those explanations.