ShellCheck can catch many bug risks in shell scripts: we encourage running it against all scripts. There is also a Code Climate engine available wrapping ShellCheck: we recommend enabling this engine on repos that contain significant shell scripts.
/bin/sh
should be preferred to /bin/bash
for compatability unless Bash-only
features are really needed. Be aware that many modern systems actually alias
/bin/bash
to /bin/sh
, so if you use Bash-isms accidentally you may not
realize it. If you want to be sure your shell is sh
-compliant, you may want to
install the [dash
] shell & use that to test your scripts.
By the same token, using POSIX flags & functionality that will work between most flavors of *nix is preferred when possible.
All scripts should call set -e
to ensure the script will exit immediately if
any intermediate command errors.
Names of variables and functions should be snake_cased. Variable names should
not be UPPER_CASED unless being exported to the ENV
.
The general principle, of course, is that 0
indicates success and 1
indicates a general error. More complex scripts may want to define specific
codes for different kinds of errors: please refer to the Bash Scripting
Guide & sysexits
for reserved/defined codes.
One common one we use in many scripts is 64
to indicate incorrect arguments
passed to a script.
Long-form flags (e.g. ls --all
instead of ls -a
) are preferred: code is read
more often than it's written. Long flags help keep scripts easy to understand &
maintain, and written scripts don't have the same need for brevity that typing
at an interactive terminal does.
Interpolating variables within strings passed to echo
can have unexpected
results: printf
is preferred.
# Good
printf "Hello %s\n" "$name"
# Bad
echo "Hello $name"
# This is fine: no variable involved
echo "Hello world."
- Rich's sh Tricks
- IEEE Std 1003.1-2001
- Advanced Bash Scripting Guide:
a very in-depth guide to a wide range of shell scripting needs, though be
aware that it is Bash-focused & doesn't clearly say what's Bash-specific and
what's not. I wish there were a guide as good as this for POSIX
sh
.