On 28/05/2015 20:54, Martijn Dekker wrote: > I'm writing a shell function that extends the functionality of the > 'getopts' builtin. For that to work, it is necessary to call the > 'getopts' builtin from the shell function. > > The POSIX standard specifies that OPTIND and OPTARG are global > variables, even though the positional parameters are local to the > function.[*] This makes it possible to call 'getopts' from a function by > simply passing the global positional parameters along by adding "$@". > > My problem is that dash does not properly update the global OPTIND > variable when getopts is called from a function, which defeats my > function on dash. It updates the global OPTIND for the first option but > not for subsequent options, so OPTIND gets stuck on 3. (It does > accurately update the global OPTARG variable, though.) That isn't the problem, not exactly anyway. The problem is that getopts is required to keep internal state separately from the OPTIND variable (a single integer is insufficient to track the progress when multiple options are combined in a single word), and that internal state is stored along with the positional parameters. The positional parameters are saved just before a function call, and restored when the function returns. The internal state of getopts should not be saved the same way. It should probably just be global to dash. A quick patch to make sure it is global, and isn't reset when it shouldn't or doesn't need to be, is attached. You can experiment with it, if you like. Your script runs as expected with this patch. However, I should warn that I have done far too little investigation to actually submit this patch for inclusion at this point. I'll do more extensive checking, and testing, later. If someone else can check whether the patch is okay, and if not, in what cases it fails, that would be very welcome too. Note that any changes could break existing scripts, that (incorrectly) rely on dash's current behaviour of implicitly resetting the state, and don't bother setting OPTIND to explicitly reset it when they want to parse a new set of arguments. Cheers, Harald van Dijk