Well-structured scripts are easier to test, reuse, and debug.
log() { printf '[%s] %s\n' "$(date -Is)" "$*" >&2; }
do_work() {
local input="$1"
log "processing: $input"
}
local variables inside functions to avoid global pollutionreturn 0, return 1)main() {
[[ $# -ge 1 ]] || { echo "Usage: $0 <path>" >&2; exit 2; }
do_work "$1"
}
main "$@"
script.sh (entrypoint + main)lib/*.sh (reusable functions)tests/ (shell tests or bats)[[ -d "$dir" ]] || { echo "Not a dir: $dir" >&2; exit 2; }
tmp="$(mktemp -d)"
cleanup() { rm -rf "$tmp"; }
trap cleanup EXIT