Closed jpco closed 11 months ago
I favor an internal POSIX getopt implementation.
As you said, it's not difficult, and it's a bad idea to rely on GNU getopt behavior like the +
prefix or the POSIXLY_CORRECT
environment variable when compiling on other systems that aren't necessarily GNU-based.
To make things clearer for those who might be confused about what's going on:
./coolscript -x
is executed by a user.#!/usr/local/bin/es
is seen in ./coolscript
, so /usr/local/bin/es ./coolscript -x
is what's actually executed by the system.getopt()
to parse options, resulting in the reordered /usr/local/bin/es -x ./coolscript
.-x
and enables tracing, then moves to the next argument ./coolscript
, which it begins executing as a script../coolscript
never sees the -x
option that was intended for it.
This seems to be all GNU's fault. They decided to be "helpful" by making GNU getopt parse ALL options in argv, rather than stopping at the first non-option arg as the POSIX spec states. Several libcs have imitated GNU in doing this. Several others follow POSIX.
This is 1. inconsistent with every other shell, 2. inconsistent with es' own man page, and 3. badly surprising in certain cases. See this example:
This can be worked around by adding "+" to the front of the
optstring
arg togetopt()
, but that's an imperfect solution because some implementations will barf if the "+" is present. (You can also setPOSIXLY_CORRECT=1
in the env when invoking es, but ... ew.)I see two good options here: 1. roll es' own opt-getting logic (it's not terribly hard to do); or 2. set up some autoconf magic to detect whether the local getopt understands "+".