1

I currently have a script that is using short flags -M, -m, and -b. I only want to make use of one argument, so I just have it break on the matching flag. I would like to change it so that it returns a non-zero code if more than one flag is used, and I'd like to support long flags (--major, --minor, --bug). How can I modify this block of code I use now to achieve that?

while getopts ":Mmb" increment; do
  case "${increment}" in
    M)
      result=1
      break
      ;;
    m)
      result=2
      break
      ;;
    b)
      result=3
      break
      ;;
  esac
done
Cyrus
  • 84,225
  • 14
  • 89
  • 153
TomNash
  • 3,147
  • 2
  • 21
  • 57
  • couple options .. 1) keep track of the number of options processed and if option count > 1 then generate a message and a non-zero exit/return code; 2) unset 3x variables, save each option in a separate variable, after `getopts` completes check for more than one variable being set and if so generate a message and a non-zero exit/return code; as for how to process a mix of short and long options ... I would suggest googling 'getopts long short options' ... lots of hits on that like [this one](https://stackoverflow.com/questions/402377/using-getopts-to-process-long-and-short-command-line-options) – markp-fuso Feb 05 '20 at 18:00
  • 2
    ... Or simply fail with a wail if `result` is already set. – tripleee Feb 05 '20 at 18:07

1 Answers1

4

Perhaps:

has_M=0
has_m=0
has_b=0

while getopts ":Mmb" increment; do
  case "${increment}" in
    M) has_M=1 ;;
    m) has_m=1 ;;
    b) has_b=1 ;;
  esac
done
shift $((OPTIND - 1))

if (( has_M + has_m + has_b > 1 )); then
    echo "only one of -M -m -b is allowed" >&2
    exit 1
fi

if ((has_M)); then
    :# do -M stuff
elif ((has_m)); then
    :# do -m stuff
elif ((has_b)); then
    :# do -b stuff
fi
glenn jackman
  • 238,783
  • 38
  • 220
  • 352