Bash Scripting Guidelines

At Quoin, we often use shell scripts as an important tool for client and company infrastructure projects. Our project teams have used scripting for specific requirments in a range of applications, including process automation, data management, and deployment. Members of our engineering staff therefore need to follow good coding practices to ensure that shell scripts work correctly. Additionally, for any scripts that are part of a prdouction system, the code should be maintainable, portable, and robust. Below are our guidelines for developers.

1. Program to the POSIX standard

This provides the best level of portability and performance. The standard is
based on the Bourne shell so alternate shells such as csh, zsh, ... shouldn't
be used for scripts. For interactive shells, use whatever you like.

2. Always enable basic verification capabilities.

Generally you want at least the following. The -u option warns about
dereferencing an undeclared variable. The -e option enables automatic exit on
an error.

    set -u -e

3. Use static verification tools.

At a minimum use the following. Both are available in Debian. checkbashisms is
part of the devscripts package. On qinux, make sure to install the jessie-
backports version.

    $ shellcheck -s 'sh'
    $ checkbashisms --posix --extra --newline --force

These tools will catch quite a few non-portable or questionable coding
practices. Keep in mind they are quite limited compared to tools such as Java
checkstyle or C/C++ flexelint.

4. Use unit test framework.

We use shunit2 available in Debian. Your scripts have to be constructed to
support unit testing so at a minimum don't hard-code file system locations.

5. Verify with appropriate interpreter.

Make sure to use an interperter as close to the POSIX standard as possible for
testing. On qinux, use the following:

    $ dash
    $ lksh -o posix -o sh
    $ bash --posix

dash is the default on Debian for non-interactive scripts. lksh is part of
mksh (make sure to use the backport version). It is the closest interperter to
the Korn shell which is the default on all commercial Unix system, including
AIX at Lowe's. bash is used so extensively that you want to verify that your
scripts will work with it as well. At Lowe's, bash is the shell used in
Windows through cygwin (and maybe eventually Windows 10).

On commercial Unix such as AIX at Lowe's, always use /bin/sh which will
usually enable POSIX mode even though it may actually be the Korn shell.

6. Get your scripts reviewed.

The shell command language is weird with lots of potential for errors.
Definitely ask for a code review but only after you've verified everything you

7. Good references

Bash Beginners Scripting Guide - A concise introductin

Advanced Bash-Scripting Guide - An in-depth exploration of the art of shell scripting
Mendel Cooper

This is a great guide with lots of useful information. It's specific to Bash
but you can usually translate to POSIX.

empty - Run processes and applications under pseudo-terminal (expect

This is a replacement for expect when you need to write scripts that interact
with CLI programs. This is available in the Debian empty-expect package.