[Toybox] --help

Rob Landley rob at landley.net
Sun Apr 7 22:52:52 PDT 2013


On 04/05/2013 03:12:18 PM, Jeremy Huntwork wrote:
> Hi, I'm a bit confused about how help text should operate. To me it
> would make sense to be a universal option which toybox handled for
> every command, but I'm seeing unexpected results.

There's a help command.

   ./toybox help cat

In bash (and possibly posix?) the "help" command gives you help on  
shell builtins. I've been meaning to add "man" as well (because unix  
guys are used to going "man cat"), but need to figure out what data  
format external man pages should live in, or whether to hand off to an  
external man command...

Doing --help is mostly a gnu-ism, which got picked up by busybox. I can  
add it to the base help parser if you like, and have toybox have a  
--help mode.

I also note that the help text subsystem has pending todo items.  
Specifically if you have more than one config item (or more than one  
command sharing a main() function, ala md5sum and sha1sum), it doesn't  
process the help text enough to provide the the intended output.

For example, CONFIG_DF has the sub-option CONFIG_DF_PEDANTIC. Each  
starts with a usage line, ala:

     usage: df [-t type] [FILESYSTEM ...]
     usage: df [-Pk]

what _should_ happen is the usage lines get combined into:

     usage: df [-Pk] [-t type] [FILESYSTEM ...]

And then the rest of the help text for both options in order after  
that. But it doesn't. Part of this is that the help text processing is  
currently done in python (which is why generated/help.h gets put in the  
release tarballs, so we don't require python on the host as a build  
dependency), and I don't want to extend that but instead replace it  
with a C implementation. _That_ should parse the help text and do the  
full set of processing to merge usage lines and glue together related  
help entries. (And figure out what to do about sha1sum giving you the  
help text for md5sum.)

I.E. there's known todo items here, at the design level.

> For example:
> 
> toybox # ln -s toybox sha1sum
> toybox # ./sha1sum
> ^C
> 
> OK, so sha1sum is expecting a file name as the first argument, seems  
> reasonable.
> But doesn't it allow specific keywords?

The problem here is:

USE_MD5SUM(NEWTOY(md5sum, NULL, TOYFLAG_USR|TOYFLAG_BIN))
USE_MD5SUM_SHA1SUM(OLDTOY(sha1sum, md5sum, NULL,  
TOYFLAG_USR|TOYFLAG_BIN))

So we're never actually -calling_ the command line option parser,  
because it has no options, no minimum/maximum number of arguments...  
there's nothing for the command line option parser to do.

Passing NULL instead of "" for the option string is a special case that  
allows the option parser to drop out entirely and not take up space in  
the binary if you're only building commands that don't use it. (Such as  
the "build each toybox command as a separate binary" case. which is on  
my todo list...)

> toybox # ./sha1sum --help
> sha1sum: --help: No such file or directory
> toybox # ./sha1sum -h
> sha1sum: -h: No such file or directory
> toybox # ./sha1sum help
> sha1sum: help: No such file or directory
> 
> Guess not. Maybe toybox does?

It's still not calling the command option parser, so it treats anything  
you feed it as a filename.

> toybox # ./toybox help sha1sum
> usage: md5sum [FILE]...
> 
> Calculate md5 hash for each input file, reading from stdin if none.
> Output one hash (16 hex digits) for each input file, followed by
> filename.
> 
> OK, good, but it's the wrong help text, apparently because md5sum and  
> sha1sum
> share the same c file:

As stated above, there are known todo items. (This came up on the list  
before, a year or so back. If I was online I'd try to dig up a web  
archive link...)

> toybox # grep -A 7 help toys/lsb/md5sum.c
>   help
>     usage: md5sum [FILE]...
> 
>     Calculate md5 hash for each input file, reading from stdin if  
> none.
>     Output one hash (16 hex digits) for each input file, followed by
>     filename.
> 
> config MD5SUM_SHA1SUM
> --
>   help
>     usage: sha1sum [FILE]...
> 
>     calculate sha1 hash for each input file, reading from stdin if  
> one.
>     Output one hash (20 hex digits) for each input file, followed by
>     filename.
> */
> 
> Also, I find it interesting on some commands that --help is an unknown
> flag, which then actually does what I want and spits out the usage:

Yup. That's intentional. But it can't be an unknown flag if the command  
parser is disabled for the command.

I could change the behavior to enable the command parser any time it's  
compiled in, but then it's hard to make it drop out when it shouldn't  
be there. (I could give it a config option, but that's micromanaging  
infrastructure in a way I try to avoid...)

Really I need a toybox version of the scripts/individual.sh thing I did  
for busybox many moons ago, and then have _that_ do the drop out  
thing...

> toybox # ln -s toybox mkdir
> toybox # ./mkdir --help
> usage: mkdir [-p] [-m mode] [dirname...]
> Create one or more directories.
> 
> -p  make parent directories as needed.
> -m  set permissions of directory to mode.
> 
> mkdir: Unknown option help
> 
> Is there an acceptable way to standardize this across all toys?

As explained above: the help infrastructure has known todo items.

Another busybox-ism people seem to expect is "busybox --help command"  
(which is seperate from "busybox command --help" even though it  
produces the same output. I haven't implemented either because what I'd  
really like is "man cat". what I _have_ right now is "help cat".)

If you really want consistency, I can filter out "--help" specially and  
always ignore it. But I doubt that's what you really want.

> JH

Rob



More information about the Toybox mailing list