Search code examples
bashgetopts

getopts checking for mutually exclusive arguments


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

Solution

  • 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