This is an old revision of the document!
argp.sh
argp.sh(1) is a bash(1) wrapper around getopt(1) to make life much easier for script developers. It's used in most of my scripts - look at them for examples of use. There's just one essential file to install - the script itself. Put it somewhere on your path, typically in /usr/local/bin
.
To use argp.sh(1), a script pipes in a description of its options (in XML or plain text) and gets back the variables as processed by getopt(1) - as a plus it also provides automatic help and man page production.
It buys you:
- all the goodness of getopt(1)
- define options in one central place together with descriptions.
- fewer 'magic' and duplicated values in your code
- better consistency between
- the getopt(1) calling parameters,
- the case statement processing the user's options and
- the help/man pages
- less spaghetti in your own code
- much, much easier to maintain
- automatic help-page and man-page printing using the same data sources
- checking of option consistency at runtime
- range checking of option values at runtime
- pretty easy to use (just copy and paste from one of my example scripts)
- portable to OS's without long option support - the help page adapts too
Note that argp.sh(1) deprecates an older script that I wrote called process-getopt(1).
There is also a 'c' version of argp.sh(1) in case you need speed.
Download & repo
- Homepage, Releases and Repository: Sourceforge
To get the latest version of the full source code:
svn checkout svn://svn.code.sf.net/p/argpsh/code/trunk argpsh-code
Sample usage
This is a simple wrapper around find(1) but it has enough options to make an interesting sample:
#!/usr/bin/env bash initialise() { local TEMP PROG=$(basename $0) VERSION="1.2" TYPE="f" ARGUMENTS="[pattern]" SHORT_DESC="Search for filenames in sub-directories." USAGE="Presently this is just a shorthand for: find . -follow -type $TYPE -name '*pattern*' -print 2>/dev/null |sort" NEW_ARGS=( ) ARGS=" ARGP_DELETE=quiet ARGP_VERSION=$VERSION ARGP_PROG=$PROG ARGP_PREFIX=FOO_ ############################################################## #OPTIONS: #name=default sname arg type range description ############################################################## EXCLUDE='' x directory s '' exclude directory. DIR='f' d '' b 'd' search for a directory rather than a file. CD='' C directory s '' search from this directory rather than cwd. ############################################################## ARGP_ARGS=[--] $ARGUMENTS ARGP_SHORT=$SHORT_DESC ARGP_USAGE=$USAGE" TYPE='f' exec 4>&1 eval "$(echo "$ARGS" | argp.sh "$@" 3>&1 1>&4 || echo exit $? )" exec 4>&- TYPE="$FOO_DIR" [[ "$FOO_CD" ]] && { cd "$FOO_CD" || exit 1 } NEW_ARGS=( "$@" ) return 0 } main() { set -o noglob SEP='' for EXCLDIR in .svn .git nbproject .libs .deps CVS* $FOO_EXCLUDE; do EXCLDIRS+="$SEP -path */$EXCLDIR " SEP=" -o" done [[ "$FOO_VERBOSE" ]] && set -x find . -follow \( $EXCLDIRS \) -prune -o -type $TYPE -name "*$1*" -print 2>/dev/null |sort } initialise "$@" && set -- "${NEW_ARGS[@]:-}" main "$@"
Here is the output from the –help option auto-generated by argps.sh(1):
Usage: ff [OPTION...] [--] [pattern] Presently this is just a shorthand for: find . -follow -type f -name '*pattern*' -print 2>/dev/null |sort Options: -C, --cd=directory search from this directory rather than cwd. -d, --dir search for a directory rather than a file. Default is 'f'. -v, --verbose be verbose -x, --exclude=directory exclude directory. -h, --help print this help message -V, --version print version and exit
See the rules for processing options to see just how hard it is without getopt(1) !!!