tested on macos and openbsd
when i write shell scripts i follow these rules. feel free to fork this guide

posix shell guide

follow shellcheck rules

format with shfmt

defaults

use base system binaries, avoid 3rd-party packages

use simplest tool possible

# do
echo ${0##*/}

# avoid
echo "$0" |
    sed 's,*/,,'

trap

with background jobs use trap

test

use test, avoid [ ] and [[ ]]

# do
test -n "$1" || exit 1

# avoid
[ -n "$1" ] || exit 1

avoid mutations if possible

avoid nesting

split functions into short, avoid long functions

use local variables if possible

unset variables as soon as possible

# do
fail() {
    echo "$@" >&2
    exit 1
}

test -f "$1" ||
    fail "$1 not found"

file="$1"

if
    test -f "$1"
then
    file="$1"
else
    echo "$1 not found" >&2
    exit 1
fi

name functions as verb_noun

avoid function keyword

# do
render_page() {
...
}

# avoid
function render_page() {
...
}

use if then else

use pipe

use set -eu

use for x in $xs

add new line after && || | , unless it ends with one word

use lowercase for variables

use UPPERCASE for constants

© roman zolotarev