On Wed, Jun 20, 2018 at 05:16:48PM +0900, Hyunho Cho wrote: > set -- -a -bc hello world > > echo $OPTIND # sh, bash = 1 > > getopts abc opt "$@" > echo $opt, $OPTIND # sh, bash = a, 2 > > getopts abc opt "$@" # bash = b, 2 <------ > different from "sh" > echo $opt, $OPTIND # sh = b, 3
(There is no "sh". There are just differing implementations of the POSIX standard. If you meant "dash", then yes, I get the same results as you using bash and dash.) POSIX says, Each time it is invoked, the getopts utility shall place the value of the next option in the shell variable specified by the name operand and the index of the next argument to be processed in the shell variable OPTIND. After your second call to getops, the second argument is only half-way processed. Your third call to getopts will still be processing the second argument. So, it's unclear what OPTIND should contain at that point. Since POSIX doesn't say anything about what OPTIND should contain when you're in the middle of processing an argument with multiple concatenated options inside it, I'd say that this falls into the realm of "unspecified behavior", and shells can do anything they want. So, not a bug in bash. Or in dash. Or in ksh, which by the way does the same thing as bash. I really don't understand what you're doing here, either. The only use of OPTIND is after the final call to getopts, when there are no more options to process. At that point, OPTIND tells you how many times you have to "shift" to get rid of all the options that were processed. (And you have to subtract 1, because legacy historical reasons.) Any attempt to use OPTIND in the middle of the loop seems pointless and hazardous to me. If you want the option-argument of an option that takes one, it's in the OPTARG variable. You use that inside the while getopts loop. (Your example didn't have any options with arguments, so I'm still puzzled as to what you're actually trying to do.)