0

I have a script that has the following line:

while getopts "b:?1:?2:?g:r:n:t:?o:?" opt; do

how is this any different than:

while getopts "b:1:2:g:r:n:t:o:" opt; do

Brian Wiley
  • 485
  • 2
  • 11
  • 21
  • 1
    On what operating system and in what shell is that script? What research did you do? And you tagged `getopt` not `getopts` - they differ, a lot. The `?` in `getopts` used as a option character is just invalid. Is the script available on the internet? Did you ask the author of the script what he meant? I _guess_ the author meant that the option argument is optional, I wonder if such implementation exists. Is there a custom `getopts` implementation in the script? – KamilCuk Jan 21 '21 at 07:52
  • 1
    sorry it is `getopts` with an `s`. Ubuntu and bash but I found it in a CWL script. I can try to change the tag. I read a lot of different pages such as https://www.computerhope.com/unix/bash/getopts.htm and https://www.ibm.com/support/knowledgecenter/ssw_aix_71/g_commands/getopts.html but they only refer to `?` as being special character set to $opt. Script is here https://github.com/litd/analysis-workflows/blob/master/definitions/tools/sequence_align_and_tag.cwl – Brian Wiley Jan 21 '21 at 07:55

1 Answers1

1

how is this any different than:

The first one is invalid. It's as different, as ? will be most probably ignored by most getopts implementations, but if getopts decided to error on invalid optstring that would be fine. From posix getopts:

optstring

A string containing the option characters recognized by the utility invoking getopts. [...]

The characters <question-mark> and <colon> shall not be used as option characters by an application. [...]

There are no other mentions of ?, except for error handling. getopt is a really simple utility, the ? is returned by getopt in case of parsing error.

The author most probably meant to do "optional option argument" - getopt does not support such functionality (and if it would, I believe it would be denoted by two :: like in GNU getopt).

Looking at bash sources getopt.c, bash uses simple strchr to scan for the option in optstring. Because there's ?, it is interpreted as an option - it becomes impossible (or unnecessary hard) to differentiate between error and success, as ? is returned in case of error.

$ OPTIND=0; set -- -'?' -g; while getopts "something:?does_not_matter" opt; do echo "$opt" "$OPTARG"; done
?                                              # This is valid -? option
bash: option requires an argument -- g
?                                              # This is error

$ OPTIND=0; set -- -'?'; while getopts "something:does_not_matter" opt; do echo "$opt" "$OPTARG"; done
bash: illegal option -- ?
?                                              # This is error
KamilCuk
  • 120,984
  • 8
  • 59
  • 111