getopts checking for mutually exclusive arguments

Chris Snow picture Chris Snow · Feb 12, 2014 · Viewed 8.7k times · Source

I have a simple script (below) that has mutually exclusive arguments.

The arguments for the script should be ./scriptname.sh -m|-d [-n], however, a user can run the script with ./scriptname.sh -m -d which is wrong.

Question: how can I enforce that only one of the mutually exclusive arguments have been provided by the user?

#!/bin/sh

usage() {
   cat <<EOF
Usage: $0 -m|-d [-n]
where:
    -m create minimal box
    -d create desktop box
    -n perform headless build
EOF
   exit 0
}

headless=
buildtype=

while getopts 'mdnh' flag; do
  case "$flag" in
    m) buildtype='minimal' ;;
    d) buildtype='desktop' ;;
    n) headless=1 ;;
    h) usage ;;
    \?) usage ;;
    *) usage ;;
  esac
done

[ -n "$buildtype" ] && usage

Answer

anubhava picture anubhava · Feb 12, 2014

I can think of 2 ways:

Accept an option like -t <argument> Where argument can be desktop or minimal

So your script will be called as:

./scriptname.sh -t desktop -n

OR

./scriptname.sh -t minimal -n

Another alternative is to enforce validation inside your script as this:

headless=
buildtype=

while getopts 'mdnh' flag; do
  case "$flag" in
    m) [ -n "$buildtype" ] && usage || buildtype='minimal' ;;
    d) [ -n "$buildtype" ] && usage || buildtype='desktop' ;;
    n) headless=1 ;;
    h) usage ;;
    \?) usage ;;
    *) usage ;;
  esac
done