Course page
Log in

You are watching a free preview. Enroll to open all 24 lessons, track progress and ask the course tutor.

Enroll for $29.99

Section 1: Foundations of reliable scripts

Anatomy of a good script

Video 9 min Lesson 1 of 24 Sample clip Preview

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 bash is the shebang. It tells the system to run the file with Bash found on the PATH. Do not use #!/bin/sh if you use Bash features; on Debian and Ubuntu sh is dash, a different shell.
  • set -euo pipefail enables 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.
  • readonly prevents accidental reassignment.
  • Every variable expansion is in double quotes. This is the single most important habit in Bash.
  • -- after mkdir -p marks the end of options, so a directory name starting with a dash is not mistaken for an option.
  • Wrapping the logic in main and calling main "$@" 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.

← → switch lessons