Bash — House Rules
Who this is for — anyone writing a canary, a build script, or any glue in these repositories. Reference material: grep it, don’t read it.
Read this if — you are about to type
[[.
Skip this if — you want the reasoning behind the subset; that is How to Read the House Rules.Takeaways
set -euo pipefail, always, on line two.if test …— never[ … ], never[[ … ]], andthen/else/doon their own lines.- Quote every expansion; assume the default
awkis mawk.
Bash is an incredibly powerful glue language when restricted to its robust, readable features. Forget old habits and legacy scripts. This is the subset we write.
1. The Strict Header
Always start script execution with:
#!/usr/bin/env bash
set -euo pipefail
-e: Exit immediately if any command returns a non-zero status.-u: Exit if an uninitialized variable is referenced.-o pipefail: Ensure that pipeline return codes reflect the last non-zero command in the chain, not just the final command.
2. Conditionals: Use test Command
Never use the brackets [ ... ] or [[ ... ]]. Instead, use the clean and standard test command.
if test -f "$file"
then printf 'Found %s\n' "$file"
fi
if test "$a" = "$b"
then printf 'Equal\n'
else printf 'Not equal\n'
fi
- Put
then/else/doalways on their own lines. - Avoid semicolons where possible.
3. Variable Safety
- Always double-quote variables when accessing:
"$var"or"${var}". - Handle required arguments with default error patterns:
pattern="${1:?Usage: script.sh PATTERN}" - Use
localinside functions. For command substitutions, declare first, then assign, to preventlocalfrom masking execution exit codes:local result result=$(command args)
4. Alignment Continuation
Do not follow rigid N-space indents. Instead, use alignment continuation to make long command pipelines and logic structures readable:
# Line up commands under the start of the chain
result=$(some_command |
grep "pattern" |
awk '{print $2}')
# Line up conditions under the first test
if test -f "$a" &&
test -d "$b"
then stmt1
stmt2
fi
5. Output discipline
-
Use
printfinstead ofechofor printing variables:printf '%s\n' "$var". -
Write helper functions to handle pass/fail messages and stderr logging:
pass() { printf ' ✓ %s\n' "$*" } fail() { printf 'ERROR: %s\n' "$*" >&2 exit 1 }This is the shape every script under
scripts/uses — the page and the repository agree, which is the only reason to trust either.
6. Awk Portability (Warning)
On standard Debian, Ubuntu, and Raspberry Pi OS, the default awk is mawk, not gawk. Avoid gawk extensions:
- ❌ Do not use 3-argument
match(). - ❌ Do not use
strtonum(). - ❌ Do not use
gensub(). Use standard portable constructs likesplit(),sub(), andgsub().