
Self Documenting Scripts
Often documentation is the last part of a script to be written, if at all.
To avoid this trap, I find it useful to start with a barebones script
written to prioritize documentation. The script's --help output inspects
the source code for specially crafted comments.
Here's a really short example shell script to illustrate:
#!/usr/bin/env sh
## Self documenting Script
## This documentation block will appear when the help flag
## or invalid inputs are used
##
## Usage: __PROG__ [options]
##
prog="$0"
me=`basename "$prog"`
# Lines starting with '##' are intended for usage documentation
function usage() {
grep '^##' "$prog" | sed -e 's/^##\s\?//' -e "s/__PROG__/$me/" 1>&2
}
# Print usage
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
usage
exit;
fi
# Do some useful script task
echo "This script has help. Use the --help flag"
If invoked with ./script.sh -h or ./script.sh --help, you can expect output like this:
[kenbarbour]$ ./example.sh
This script has help. Use the --help flag
[kenbarbour]$ ./example.sh --help
Self documenting Script
This documentation block will appear when the help flag
or invalid inputs are used
Usage: example.sh [options]
Introspection
The key to this technique is a usage() function that reads the content of the file being executed, and prints lines that match an expression. The string __PROG__ is replaced with the current name of the script (as invoked).
Documentation can appear anywhere within the script. This technique can be adapted to many other languages, and used for even more complex situations.
Further Steps
This technique isn't limited to grepping for comments for usage only. More complex comment patterns could be constructed for different kinds of documentation, such as usage for sub-commands.
There is also room for more string replacement options, like replacing __PROG__ with the name of the script. Hopefully you'll add this technique to your starter script and be a step ahead in writing well documented scripts.
Resources
I discovered this technique from a blogpost by Jim Jackson on The Linux Daily. The domain has transferred owners and is no longer serving the same blog, but I've tracked the original post on the Wayback machine