shell/README.md
|, &&, or || and indent the continuations.then or do, use if ...; then and while ...; do.for x; do, not for x in "$@"; do.snake_case for variable names and ALLCAPS for environment variables.ls. Understand why you shouldn't and available
alternatives.cat to provide a file on stdin to a process that accepts file
arguments itself.echo with options, escapes, or variables (use printf for those
cases)./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)./bin/sh shebang.cd, have code to handle a failure to change directories.rm with a variable, ensure the variable is not empty.awk '/re/ { ... }' to grep re | awk '{ ... }'.find -exec {} + to find -print0 | xargs -0.for loops over while read loops.grep -c to grep | wc -l.mktemp over using $$ to "uniquely" name a temporary file.sed '/re/!d; s//.../' to grep re | sed 's/re/.../'.sed 'cmd; cmd' to sed -e 'cmd' -e 'cmd'.if statements (if grep -q ...;, not if [ -n "$(grep ...)" ];).$TTY not $(tty),
$PWD not $(pwd), etc).$( ... ), not backticks for capturing command output.$(( ... )), not expr for executing arithmetic expressions.1 and 0, not true and false to represent boolean variables.find -print0 | xargs -0, not find | xargs."$variable" and "$( ... )" expression unless you
want them to be word-split and/or interpreted as globs.local keyword with function-scoped variables.