A Useful Shell Pattern
If you work at the unix command line you probably execute pipelines of programs to test ideas. It’s part of the unix way. Sometimes you need a little more than a simple pipeline. A small shell script here or there is an easy lightweight way to provide a slighly larger pipeline component or to wrap several components for repeated execution.
Often I find myself writing such a script that processes data differently to provide related but distinct manipulations of the data, handle multiple input or output formats, or apply similar processing to distinct source types. When this happens I use the following simple pattern:
shell-script mode [mode-args]
Here mode selects the shell script execution path, and different modes may take different arguments.
At the top level of such a script I use a case statement that dispatches execution to a shell function named for the mode:
case "$1" in
mode1|mode2|mode3)
"do_$@"
;;
*)
printf 'usage statement'
exit 1
;;
esac
The purpose of the case statement is merely to constrain the available modes. Strictly speaking you don’t need it, though I recommend it.
All you need is to define a “mode function” called do_modename
and add the name of the mode to your top-level dispatch. A separate function for each mode mode makes the code flow easy to follow. Different modes can make use of the same utility functions in the script if appropriate. And you can repeat the "do_$@"
pattern internally if additional layers of dispatch are needed.
This top-level dispatch to mode-specific functions makes it easy to create clean scripts to handle multiple modes. Adding new modes is highly modular. Modes need not share arguments, as all arguments beyond the mode are handled by the mode function itself.
One mode may even pipe several others together by calling their mode functions, handling the combined arguments at the top level and passing them down as needed.
This is one way in which shell remains underrated.