GGistDev

Scripting Basics

Write maintainable scripts with proper shebangs, permissions, linting, and style.

Shebang and strict mode

#!/usr/bin/env bash
set -euo pipefail
# -e: exit on error; -u: error on unset; -o pipefail: fail pipeline on any error

Use #!/usr/bin/env bash for portability across systems.

Permissions and execution

chmod +x script.sh
./script.sh

Place scripts on PATH (e.g., ~/bin) or invoke with ./.

Linting with shellcheck

shellcheck script.sh

Fix warnings for quoting, undefined vars, array pitfalls. Many editors integrate ShellCheck.

Style guidelines

  • Quote all parameter expansions: "$var", "$@", "$(cmd)"
  • Prefer $(...) over backticks
  • Use [[ ... ]] for tests; (( ... )) for arithmetic
  • Use functions and local variables to limit scope
  • Name scripts and functions descriptively; use usage() for help

Arguments and usage

usage() { echo "usage: $0 [-f file] [--verbose]"; }
while [[ $# -gt 0 ]]; do
  case $1 in
    -f|--file) file=$2; shift 2;;
    -v|--verbose) verbose=1; shift;;
    -h|--help) usage; exit 0;;
    *) echo "unknown: $1"; usage; exit 2;;
  esac
done

Directory structure

project/
  bin/           # executables
  lib/           # sourced helpers (". lib/common.sh")
  scripts/       # operational scripts

Logging

log() { printf '[%(%F %T)T] %s\n' -1 "$*"; }

Summary

  • Use a portable shebang, strict mode, and ShellCheck
  • Quote expansions, structure with functions, and provide clear usage