Unixscripts: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:

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) !!!