User Tools

Site Tools


Decent Bash

Here's my five penn'orth. A bash script (actually any program!!) should:

Use getopt(1)

Use getopt(1) to process command line arguments. There are many good reasons for this. Just do it. Let me count (some of) the ways:

  • provides a rational, predictable user interface - compare the nasty old peculiarities of tar and find!!
  • supports short option merging eg foobar -s -f -t == foobar -sft
  • disambiguates option argument spacing eg foobar -z1 == foobar -z 1
  • re-orders options so they can be processed and then popped and forgotten
  • supports to terminate options
  • plain old simple works - why write bug-prone new code when getopt(1) just works?


Even better, use my getopt(1) wrapper which is kinda sorta like GNU's argp(3) in glibc. It gives you a single place to define options which is then used to:

  • create the getopt(1) command line,
  • process the options setting appropriate environment parameters
  • print help & man pages without any extra code
  • honours GNU's ARGP_HELP_FMT environment variable
  • is pretty similar to GNU's argp(3) which is a getopt(3) wrapper in glibc
  • further reduces the chance of bugs arising - particularly as the script is maintained
  • increase the chance that help and man pages are actually written

Support Long options

Always provide long options as well as single letter options - they're more mnemonic for infrequent users and provide valuable documentation when scripted.

Provide help

respond to the -h, –help option with a usage message to !!!STDOUT!!! and exit 0. This help should be available no matter what the machine's state - so issue it before looking for dependencies and without making assumptions about what is installed.

If there are specific dependencies, then make sure they are documented in the help message.

Provide version info

provide a way to get the program's version eg -V, –version to !!!STDOUT!!! and exit 0

Note that -h and -V processing should happen before any other substantial processing or checking is done - make sure -h can always be done no matter what

Be disciplined with error messages

Error messages should go to !!!STDERR!!! - do not print the usage as it just fills the screen and hides the meat of the error. At the most, refer the user to the usage page with run 'foobar -h' for help or 'man foobar' for a reference manual.

Be disciplined with error exit codes

non-zero exit on any error

Silence is golden

execute as silently as possible so the user doesn't have to scour through copious output. If feedback on progress is needed, just “echo -n .”

The exception, of course, is if a verbosity command is given, generally with -v, –verbose - and the output goes to stdout, thank you very much (so we can distinguish bash's own -x output which goes to stderr)

man(1) page

include a man page if non-trivial

Use a crunchbang

always include the crunchbang as the first line:

#! /usr/bin/env bash

Structure the code

use subroutines heavily - only put the following in the mainline:

process_options "$@"
main "$@"
decentbash.txt · Last modified: 2016/10/05 12:59 by admin