Search code examples
bashshellgetopts

How to enforce only the use of one flag in a shell script?


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

Solution

  • 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