[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: getopts - mutually exclusive flags
From: |
Bob Proulx |
Subject: |
Re: getopts - mutually exclusive flags |
Date: |
Sat, 1 Nov 2008 12:48:38 -0600 |
User-agent: |
Mutt/1.5.13 (2006-08-11) |
Chris Jones wrote:
> How do I handle mutually exclusive flags with getopts?
Not seeing any other answers I might as well chime in. I usually use
the 'getopt' way and not the 'getopts' way, because I have always used
getopt. And the GNU version handles long options (--long-opt). GNU
standards require long options along with --version and --help and
that pushes me to getopt.
But with getopts you should find this reference is useful:
http://www.opengroup.org/onlinepubs/009695399/utilities/getopts.html
> But I'd like to be able to run it manually and specify via flags the
> backup I want to run - daily/incremental or monthly/full.
>
> $ backup -d # daily backup
> $ backup -m # monthly ..
Sure.
> So far my best effort still finds the following acceptable:
>
> $ backup -dm
>
> I'm trying to use getopts to implement an exclusive OR of the two
> options.
As far as I know with all of the option parsing routines available you
would need to code this type of validation in yourself. The
combinatorial explosion of combinations of valid and invalid options
are not something that option parsing libraries can handle. Therefore
you need to check for validity after the options have been read.
> Incidentally, I am also curious of the "getopts" way to handle the
> absence of _any_ flags.
Again, AFAIK you would need to handle this in your code.
Here is a quick example of the way that I normally do these types of
things in my scripts. I am cutting and pasting and may make a typo
here though so it would all need to be tested. I probably should turn
this more into a distributable example. But hopefully it will be
useful as it is regardless.
#!/bin/sh
# Short summary description of your program.
# Copyright 2008 Bob Proulx <bob@proulx.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Longer description here as needed.
#
# Examples:
#
# progname arg1
# progname --verbose arg1 arg2
progname=$(basename $0)
version=@VERSION@
print_usage()
{
# This script is designed to use help2man to build the man page
# directly from the script itself.
# help2man programname
# Check the man page formatting after making changes here.
cat <<'EOF'
Description of script goes here.
This is both your man page when run through help2man and your online
help. Document your program here.
Usage: programname [options]
Options:
-v, --verbose verbose operation
-n, --dry-run not really, just print what would be done
--help print this help message
--version print program version
Examples:
$ programname --help
$ programname --verbose --dry-run
$ programname arg1 arg2
Report bugs to <bug-address@example.com>.
EOF
}
print_version()
{
echo "$progname $version"
echo "Copyright (C) 2008 Your Name <you@example.com>."
echo "License GPLv3+: GNU GPL version 3 or later"
echo "<http://gnu.org/licenses/gpl.html>"
echo "This is free software: you are free to change and redistribute it."
echo "There is NO WARRANTY, to the extent permitted by law."
echo ""
echo "Written by Your Name <you@example.com>."
}
SHORTOPTS="dmnv"
LONGOPTS="daily,monthly,help,verbose,version"
if $(getopt -T >/dev/null 2>&1) ; [ $? = 4 ] ; then # New longopts getopt.
OPTS=$(getopt -o $SHORTOPTS --long $LONGOPTS -n "$progname" -- "$@")
else # Old classic getopt.
# Special handling for --help and --version on old getopt.
case $1 in --help) print_usage ; exit 0 ;; esac
case $1 in --version) print_version ; exit 0 ;; esac
OPTS=$(getopt $SHORTOPTS "$@")
fi
if [ $? -ne 0 ]; then
echo "'$progname --help' for more information" 1>&2
exit 1
fi
eval set -- "$OPTS"
daily=false
monthly=false
verbose=false
while [ $# -gt 0 ]; do
: debug: $1
case $1 in
-d|--daily)
daily=true
shift
;;
-m|--monthly)
monthly=true
shift
;;
--help)
print_usage
exit 0
;;
-n|--dry-run)
notreally=true
shift
;;
--quiet)
quiet=true
shift
;;
-v|--verbose)
verbose=true
shift
;;
--version)
print_version
exit 0
;;
--)
shift
break
;;
*)
echo "Internal Error: option processing error: $1" 1>&2
exit 1
;;
esac
done
if $daily && $monthly; then
echo "Error: Both daily (-d) and monthly (-m) were specified." 1>&2
exit 1
fi
if ! $daily && ! $monthly; then
echo "Error: Neither daily (-d) nor monthly (-m) were specified." 1>&2
exit 1
fi
$verbose && echo "Processing..."
if $daily; then
echo "Doing daily stuff..."
fi
if $monthly; then
echo "Doing monthly stuff..."
fi
exit 0
Hope this helps,
Bob
- Re: getopts - mutually exclusive flags,
Bob Proulx <=