[RFC PATCH 07/11] cmd: echo: Use getopt() with '+' prefix for option parsing
Simon Glass
sjg at chromium.org
Wed May 20 22:41:24 CEST 2026
Hi Sean,
On Fri, 15 May 2026 at 15:58, Sean Anderson <seanga2 at gmail.com> wrote:
>
> On 5/15/26 16:32, Simon Glass wrote:
> > The 'echo' command's option parser is a single strcmp against argv[1]
> > that decides whether to suppress the trailing newline. Convert it to
> > getopt() so echo follows the same shape as the other commands in this
> > series and exercises the '+' prefix that POSIX-style 'stop at first
> > non-option' callers need.
> >
> > The optstring uses the '+' prefix to preserve bash echo behaviour: -n is
> > honoured only as the very first argument, so 'echo hello -n' still
> > prints 'hello -n\n' verbatim.
> >
> > Two minor differences from the bash builtin remain, both of which
> > the user can work around with quoting or --:
> >
> > * -x (an unknown short option) returns CMD_RET_USAGE rather than
> > printing literally; use 'echo -- -x' to print it.
> > * -nfoo (joined form) parses -n and then errors on the trailing
> > characters.
>
> Why? This introduces incompatibility with echo as it exists today as
> well as unix-style echo. We can have an (almost) completely-compatible
> echo with
>
> getopt_init_state(&gs, argc, argv);
> while (getopt_silent(&gs, "+n") == 'n')
> newline = false;
>
> for (i = gs.index; i < argc; ++i) {
> <snip>
>
> The only difference is that something like "echo -na" will result in
> "-na" and not "-na\n". IMO echo is not a good candidate for getopt
> due to its unusual argument handling. Even coreutils echo does not
> use getopt. So I think we should really leave echo as-is.
Yes, I am including this just so people can see a case where there is
only a single arg and we need ordering. It is the worst case I can
think of for getopt(). I have not yet really found a best case.
There are at least two reasons not to apply this patch: echo is
special in how it handles its args (as you say) and it would impact
nearly every board.
>
> > Add three test cases that pin down the new behaviour: trailing -n stays
> > literal, -- ends option parsing, and -- is consumed even after a
> > recognised flag. The positional loop uses getopt_pop() as an iterator.
> > CMD_ECHO selects GETOPT so the parser is linked in on boards that don't
> > already enable it.
> >
> > Signed-off-by: Simon Glass <sjg at chromium.org>
> > ---
> >
> > cmd/Kconfig | 1 +
> > cmd/echo.c | 23 ++++++++++++++---------
> > test/cmd/test_echo.c | 10 ++++++++++
> > 3 files changed, 25 insertions(+), 9 deletions(-)
> >
Regards,
Simon
More information about the U-Boot
mailing list