Script Valley
Linux & Bash for Developers
Advanced Bash & AutomationLesson 6.5

How to write production-ready Bash scripts

script header conventions, argument parsing with getopts, usage function, input validation, logging levels, locking with flock, idempotent scripts, shellcheck

Production Scripts Are Defensive, Documented, and Repeatable

A script that works on your laptop is not production-ready. Production scripts handle bad inputs gracefully, log what they do, avoid running twice simultaneously, and are safe to run multiple times with the same result (idempotent).

Argument Parsing with getopts

#!/bin/bash
set -euo pipefail

usage() {
  echo "Usage: $0 [-e environment] [-d] [-h]"
  echo "  -e  Target environment (dev|staging|prod)"
  echo "  -d  Dry run"
  echo "  -h  Show this help"
  exit 1
}

ENV="dev"
DRY_RUN=false

while getopts ":e:dh" OPT; do
  case $OPT in
    e) ENV="$OPTARG" ;;
    d) DRY_RUN=true ;;
    h) usage ;;
    ?) echo "Unknown option: -$OPTARG"; usage ;;
  esac
done

Locking and Idempotency

# Prevent concurrent execution
LOCKFILE="/tmp/deploy.lock"
exec 9>"$LOCKFILE"
if ! flock -n 9; then
  echo "Another instance is running. Exiting."
  exit 1
fi

# Idempotent: only create if not exists
mkdir -p "$DEPLOY_DIR"

# Idempotent: only install if not present
if ! command -v jq &>/dev/null; then
  apt-get install -y jq
fi

Validate with ShellCheck

Install shellcheck and run it against every script before deploying. It catches quoting bugs, undefined variable risks, and deprecated patterns that are invisible to the naked eye.

shellcheck deploy.sh