User Tools

Site Tools


argp.sh

argp.sh

argp.sh(1) is a bash(1) wrapper around getopt(1) 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
    1. the getopt(1) calling parameters,
    2. the case statement processing the user's options and
    3. 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

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
1)
See the rules for processing options to see just how hard it is without getopt(1) !!!
argp.sh.txt · Last modified: 2018/12/29 00:54 by admin