[Toybox] Subject: [PATCH] Add getopt(1).

enh enh at google.com
Wed Dec 4 14:33:27 PST 2019


On Sun, Nov 24, 2019 at 1:14 AM Rob Landley <rob at landley.net> wrote:
>
> On 11/23/19 10:18 AM, enh wrote:
> > The only real point of getopt(1) over the getopts built-in is long options.
> > That's all I've seen it used for in practice. It does seem like folks know about
> > getopts, and they do use it when short options are all they want.
>
> The reason it was still on my todo list is I wanted to write one that satisfied
> both groups of users, worked nicely as a shell builtin, and either used the
> lib/args.c plumbing or did it in the command.
>
> My main _handicap_ here is I never used getopt or getopts because I've never
> understood how either is supposed to _help_. (It's easier to just do it by hand.
> My first couple hours of research didn't make it clearer to me why anyone would
> use either, but clearly they do...)

basically it's just an interface to getopt_long(3) so you can get all
of the stuff like "-cq means -c -q" without writing *that* in shell
script.

> However, getopts is all about setting environment variables, which means it can
> only be implemented as a shell builtin, so I still have to write a getopts for
> toysh, and now we've got two that don't share code.
>
> And reading man 1 getopt spends an inordinate amount of time talking about OTHER
> VERSIONS of getopt (not getopts), and what it is or isn't compatible with, and
> to be honest this entire area seems kind of horrific...

yeah, like i said, the historic getopt didn't support long options.
(so was _only_ useful for the "-cq" stuff.) these days, it looks like
folks use the getopts builtin if they only want that, and only use
getopt(1) if they also want long options.

> (Jello-brain aside, I'm currently got a huge toysh diff implementing variable
> logic I need to reverse engineer enough to finish and apply, and I've got a
> bunch of tabs open refamiliarizing myself with what tcgetattr() and setsid() and
> such do for -i and job control and such, so not likely to open the getopts can
> of worms on top of it just now. But this also makes me reluctant to promote
> _this_ out of pending either.)
>
> >     While it was on my todo list for toysh, I'm not sure swallowing a large lump of
> >     gnu/glibc bespoke nonsense actually helps advance this ball. (Although I assume
> >     bionic copied an implementation from netbsd?)
> >
> > Correct. Apple's libc did too, so the getopt tests pass there too --- I tested
> > yesterday when I was going through all the macos_defconfig tests.
>
> "There are two versions of this plumbing in libc, which exist because each
> didn't do what the other wanted, and I"m not currently using either because they
> don't do what I want either". It's ftw.h all over again...

strictly i think everyone (glibc, BSD, musl) actually just use one
function under the covers that implements all three
(getopt/getopt_long/getopt_long_only).

ltrace suggests that busybox actually uses getopt_long(3) for both its
own argument parsing *and* for its getopt(1) implementation. i'd
actually just assumed that they had their own custom parser for normal
usage, like toybox. i'd still argue that "it's a reasonable
expectation that if you enable getopt(1), you're going to drag in the
getopt(3) family" though.

> Rob



More information about the Toybox mailing list