Skip to content

Shell Scripting Standards

Status: 🟢 Active  |  Owner: Platform Engineering

Policy

Shell scripting is discouraged for complex logic. If a script exceeds 50 lines or requires conditionals beyond simple flag checks, consider rewriting in Python or Go.

Shell scripts are appropriate for:

  • Build entry points that delegate to other tools.
  • Simple one-shot automation in CI pipelines.
  • Docker ENTRYPOINT wrappers.
  • Developer setup scripts that are rarely run.

Required Header

Every script must start with:

#!/usr/bin/env bash
set -euo pipefail
  • set -e — exit immediately on non-zero return code.
  • set -u — treat unset variables as an error.
  • set -o pipefail — a pipeline fails if any command in it fails (not just the last).

ShellCheck

All shell scripts must pass shellcheck with no errors or warnings:

shellcheck scripts/*.sh

ShellCheck is enforced in CI as part of the lint stage. Install locally:

brew install shellcheck       # macOS
apt-get install shellcheck    # Ubuntu

Linting Configuration

Add a .shellcheckrc to disable project-specific rules only where justified:

# .shellcheckrc
# Disable SC2039 in POSIX-mode scripts — we use Bash-specific features intentionally
disable=SC2039

Each disabled rule must have a comment explaining the reason.

Style Rules

Quote variables

Always double-quote variable references to prevent word splitting and glob expansion:

# ❌ Breaks if $name contains spaces
cp $source_file $dest_dir

# ✅
cp "$source_file" "$dest_dir"

Use [[ ]] over [ ]

[[ ]] is the Bash built-in and avoids many edge cases of the POSIX [ ] test command:

# ✅ Bash extended test
if [[ -f "$config_file" ]]; then
  source "$config_file"
fi

Local variables in functions

my_function() {
  local file="$1"
  local result
  result=$(process "$file")
  echo "$result"
}

Error messages to stderr

error() {
  echo "ERROR: $*" >&2
  exit 1
}

No cd without checking success

# ❌ Silent failure if directory doesn't exist
cd "$deploy_dir"

# ✅
cd "$deploy_dir" || error "Cannot enter $deploy_dir"

References


Last reviewed: 2025-Q4  |  Owner: Platform Engineering