Hi,
Has anyone done anything with GNU enhanced getopt in bash to process incoming command line parameters?
My understanding is that I have the choice of using the built-in "getopts" command within bash (on a CentOS 5.3 derivative distro), which doesn't support long options (e.g. --long-option as opposed to -l), or I can use the getopt (enhanced) 1.1.4 binary which lives in /usr/bin/getopt.
I want to use long options, so I'm using the GNU getopt binary. An example script is below. Note that there is one oddity - for compatibility with some other related scripts, I need the first parameter to be something else ... so the first few lines are intended to munch $1 and pass all the remaining parameters to getopt. I don't think that should affect anything, but I've left it in as that's how I'm currently testing it.
My problem is that I don't seem to be able to get the parsing to work as I expect. Specifically:
# ./cmd.sh . -i -o 1 input -i is -o
So the problem here is that it's quite happy to set the required parameter for -i to be -o ... when actually I was expecting it to catch that -i was missing a parameter. I think I had this working using getopts, but I need to be able to support long options now.
I've messed around a bit with several different ways of writing the case script, but not managed to get it working any better.
So, idle question ... has anyone got a script like this where the error checking is a bit more robust than the sample below?
Cheers,
Peter.
#!/bin/bash
paramArray=("${@}") unset paramArray[0] paramArray=("${paramArray[@]}")
getopt -T if [ "$?" != "4" ]; then echo GNU enhanced getopt not detected. Quitting ... exit 1; fi
# Override defaults with incoming parameters, if specified
PN=`basename $0` ARGS=`getopt --name "$PN" --longoptions input:,output:,noshort:,verbose --options i:o: -- "${paramArray[@]}"` if [ $? -ne 0 ]; then echo "Invalid option specified or expected parameter argument missing. Quitting ..." exit fi eval set -- "$ARGS"
while [ $# -gt 0 ]; do case "$1" in -i | --input) echo input $1 is "$2"; shift;; -o | --output) echo output $1 is "$2"; shift;; --noshort) echo noshort $1 is "$2"; shift;; -v | --verbose) VERBOSE=yes; shift;; --) shift; break;; esac shift done
exit;
Bad form to reply to one's own message, but I just noticed an extraneous shift appeared just before the end of the while loop in the script I posted earlier, which causes some issues. With that removed, the question still stands, tho.
Think I'm just going to have to live with it, short of using an alternative non-getopt(s) solution.
Peter.