| name | bash-idioms |
| description | Linux-OS repository bash coding standards — forbidden patterns, required idioms, performance rules, and the canonical script template. Use when writing or reviewing any .sh file in this repo. |
Required Header
#!/usr/bin/env bash
set -Eeuo pipefail
shopt -s nullglob globstar extglob dotglob
IFS=$'\n\t'
export LC_ALL=C LANG=C
Forbidden Patterns
| Pattern | Replacement |
|---|
eval | Never — use arrays |
Backticks `cmd` | $(cmd) |
for x in $(ls) | for x in */ or mapfile |
echo for output | printf '%s\n' |
function foo() | foo(){ ... } |
$(basename "$f") | ${f##*/} |
$(dirname "$f") | ${f%/*} |
$(cat file) | $(<file) |
| `cat f | cmd` |
| `cat f | grep` |
Required Idioms
has(){ command -v "$1" &>/dev/null; }
log(){ printf '%b\n' "$*"; }
warn(){ printf '%b\n' "${YLW}WARN:${DEF} $*"; }
err(){ printf '%b\n' "${RED}ERROR:${DEF} $*" >&2; }
die(){ err "$*"; exit "${2:-1}"; }
dbg(){ [[ ${DEBUG:-0} -eq 1 ]] && printf '[DBG] %s\n' "$*" || :; }
get_name(){ local -n _out=$1; _out="${2##*/}"; }
mapfile -t arr < <(grep -Ev '^\s*(#|$)' file.txt)
printf '%s\n' "${items[@]}" | xargs -r -P"$(nproc)" -I{} process {}
Trap Pattern
cleanup(){
set +e
[[ -n ${LOCK_FD:-} ]] && exec {LOCK_FD}>&- 2>/dev/null || :
[[ -d ${WORKDIR:-} ]] && rm -rf "$WORKDIR" || :
}
trap 'cleanup' EXIT
trap 'err "failed at line $LINENO"' ERR
trap ':' INT TERM
Color Palette (trans flag)
LBLU=$'\e[38;5;117m'
PNK=$'\e[38;5;218m'
BWHT=$'\e[97m'
DEF=$'\e[0m'
BLD=$'\e[1m'
Performance: Cost Table
| ❌ Expensive | ✅ Cheap |
|---|
$(command) subshell | ${var//pat/rep} |
tr | ${var,,} / ${var^^} |
basename | ${f##*/} |
dirname | ${f%/*} |
cat file | $(<file) |
Quoting Rules
- Always quote variables:
"$var", "${arr[@]}"
- Exception: intentional word-split/glob, and
$* in printf format
- Use
-- before user-supplied args to commands: rm -- "$file"
Input Validation
validate_path(){
[[ $1 =~ ^[[:alnum:]/_.-]+$ ]] || die "invalid path: $1"
[[ ! $1 =~ \.\. ]] || die "path traversal: $1"
}
validate_pkg(){
[[ $1 =~ ^[a-z0-9@._+-]+$ ]] || die "invalid pkg: $1"
}