I ran into an interesting scenario last night and, so far, my google foo has been unable to find a work around. I have a script that supports a number of arguments. A user (damn those users) didn't specify an argument for an option and the results were … unexpected.
The code:
while getopts "a:c:d:De:rs:" arg
do
case ${arg} in
a) app=${OPTARG} ;;
c) cmd=${OPTARG} ;;
d) domain=${OPTARG} ;;
D) Debug=1 ;;
e) env=${OPTARG} ;;
r) Doit=1 ;;
s) subapp=${OPTARG} ;;
*) echo "You are DISCREPANT!!";;
# *) usage "Invalid argument ${arg}::${OPTARG}" ;;
esac
done
if [ ${Debug} -gt 0 ]
then
echo "Env: ${env}"
echo "App: ${app}"
echo "Subapp: ${subapp}"
echo "Cmd: ${cmd}"
echo "Doit: ${Doit}"
echo "Debug: ${Debug}"
exit 1
fi
Specifying all the args correctly results in:
$ ./mwctl -a weblogic -c start -s admin -e trn -r -D
Env: trn
App: weblogic
Subapp: admin
Cmd: start
Doit: 1
Debug: 1
Forgetting the '-s' results in:
$ ./mwctl -D -a weblogic -c start admin -e trn -r
Env:
App: weblogic
Subapp:
Cmd: start
Doit: 0
Debug: 1
Similar results for skipping other args with options. It seems that 'case' loses its mind when presented with an OPTARG that doesn't have an OPT…
I'm at a bit of a loss as to how to catch this.
Best Answer
I would use
getopt
instead ofgetopts
:Note that when you are googling
getopts
vs.getopt
, you will find many people complaining aboutgetopt
. As far as I can tell, this is always about an older version ofgetopt
, which indeed was very buggy. My experience is, thatgetopt
has more options and is also more robust thangetopts
.To check if you have the enhanced
getopt
version, you can runIf the output is
4
, you have the enhanced version.