Search code examples
bashshellsyntaxargumentsgetopts

How to ignore invalid arguments with getopts and continue parsing?


I've the following simple code:

#!/usr/bin/env bash
while getopts :f arg; do
  case $arg in
    f) echo Option $arg specified. ;;
    *) echo Unknown option: $OPTARG. ;;
  esac
done

and it works in simple scenarios such as:

$ ./test.sh -f
Option f specified.
$ ./test.sh -a -f
Unknown option: a.
Option f specified.

However it doesn't work for the following:

$ ./test.sh foo -f

$ ./test.sh -a abc -f
Unknown option: a.

How do I fix above code example to support invalid arguments?


Solution

  • It seems getopts simply exits loop once some unknown non-option argument (abc) is found.

    I've found the following workaround by wrapping getopts loop into another loop:

    #!/usr/bin/env bash
    while :; do
      while getopts :f arg; do
        case $arg in
          f)
            echo Option $arg specified.
            ;;
          *)
            echo Unknown option: $OPTARG.
            ;;
        esac
      done
      ((OPTIND++)) 
      [ $OPTIND -gt $# ] && break
    done
    

    Then skip the invalid arguments and break the loop when maximum arguments is reached.

    Output:

    $ ./test.sh abc -f
    Option f specified.
    $ ./test.sh -a abc -f
    Unknown option: a.
    Option f specified.