- Break long lines on
|
,&&
, or||
and indent the continuations. - Don't add an extension to executable shell scripts.
- Don't put a line break before
then
ordo
, useif ...; then
andwhile ...; do
. - Use
for x; do
, notfor x in "$@"; do
. - Use
snake_case
for variable names andALLCAPS
for environment variables. - Use single quotes for strings that don't contain escapes or variables.
- Use two-space indentation.
- Don't parse the output of
ls
. Understand why you shouldn't and available alternatives. - Don't use
cat
to provide a file onstdin
to a process that accepts file arguments itself. - Don't use
echo
with options, escapes, or variables (useprintf
for those cases). - Don't use a
/bin/sh
shebang unless you plan to test and run your script on at least: Actual Sh, Dash in POSIX-compatible mode (as it will be run on Debian), and Bash in POSIX-compatible mode (as it will be run on macOS). - Don't use any non-POSIX features when using a
/bin/sh
shebang. - If calling
cd
, have code to handle a failure to change directories. - If calling
rm
with a variable, ensure the variable is not empty. - Prefer "$@" over "$*" unless you know exactly what you're doing.
- Prefer
awk '/re/ { ... }'
togrep re | awk '{ ... }'
. - Prefer
find -exec {} +
tofind -print0 | xargs -0
. - Prefer
for
loops overwhile read
loops. - Prefer
grep -c
togrep | wc -l
. - Prefer
mktemp
over using$$
to "uniquely" name a temporary file. - Prefer
sed '/re/!d; s//.../'
togrep re | sed 's/re/.../'
. - Prefer
sed 'cmd; cmd'
tosed -e 'cmd' -e 'cmd'
. - Prefer checking exit statuses over output in
if
statements (if grep -q ...;
, notif [ -n "$(grep ...)" ];
). - Prefer reading environment variables over process output (
$TTY
not$(tty)
,$PWD
not$(pwd)
, etc). - Use
$( ... )
, not backticks for capturing command output. - Use
$(( ... ))
, notexpr
for executing arithmetic expressions. - Use
1
and0
, nottrue
andfalse
to represent boolean variables. - Use
find -print0 | xargs -0
, notfind | xargs
. - Use quotes around every
"$variable"
and"$( ... )"
expression unless you want them to be word-split and/or interpreted as globs. - Use the
local
keyword with function-scoped variables. - Identify common problems with shellcheck.