Skip to content

Only sometimes, a late --help should override other errors #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
BenWiederhake opened this issue Apr 12, 2025 · 3 comments
Open

Only sometimes, a late --help should override other errors #130

BenWiederhake opened this issue Apr 12, 2025 · 3 comments

Comments

@BenWiederhake
Copy link
Contributor

According to the GNU implementation, arguments should be parsed left-to-right, early errors take precedence, and a later --help is IGNORED:

$ LC_ALL=C du -B kb --help README.* # early error overrides --help
du: invalid suffix in -B argument 'kb'
[$? = 1]

At the same time, with the same command, the OPPOSITE is true:

$ LC_ALL=C du --invalid README.* # --invalid is an error, does NOT print manpage
du: unrecognized option '--invalid'
Try 'du --help' for more information.
[$? = 1]
$ LC_ALL=C du --invalid --help README.* # late --help still counts, for some reason
du: unrecognized option '--invalid'
Usage: du [OPTION]... [FILE]...
  or:  du [OPTION]... --files0-from=F
Summarize device usage of the set of FILEs, recursively for directories.

Mandatory arguments to long options are mandatory for short options too.
  -0, --null            end each output line with NUL, not newline
<SNIP manpage>
$ echo $? # Not an error!
0

So apparently we should first parse arguments, and raise on errors within recognized options, only then check if --help exists, and only then raise on unrecognized options.

Insanity!

I'm not sure how to do this best, and I'm afraid this is incompatible with #113.

@tertsdiepraam
Copy link
Member

tertsdiepraam commented Apr 12, 2025

I'm so confused now...

Could you check this behaviour for other utils?

My guess is that the option parsing itself goes on to check for help on unrecognized options but that the loop around it doesn't? I think we could emulate it that way, but it'll be tricky.

@BenWiederhake
Copy link
Contributor Author

Fascinating! I wrote a script to check how each command and option behaves, gathering 159 data points:

  • Only two commands behave like this: du -B, du -d, du --time, as well the eight options bfhilnvw to nl.
  • About a third of all options only check validity after going through the entire command like (see e.g. cut -fbanana versus cut -fbanana --help)
  • The entire rest of all options (so far I tested) parses its argument immediately and raises an error immediately, as implemented in Make Options::apply fallible #113 (see e.g. df -Bkb and df -Bkb --help).

I'm happy to share the full results. Here's a screenshot of the partial results:

Image

Script so you can run it yourself:

test_help.sh.but-for-github-i-renamed-it-to.txt

So it seems that GNU du and GNU nl are outliers.

Maybe we want to count that as a bug in GNU du and nl? @sylvestre, do you agree and if yes do you feel like reporting that bug?

@BenWiederhake
Copy link
Contributor Author

I think I figured something out:

$ LC_ALL=C du --banana -B applepie README.md 
du: unrecognized option '--banana'
du: invalid -B argument 'applepie'
[$? = 1]

So it seems that GNU du tries to report all errors before returning, in contrast to basically all other utils:

$ LC_ALL=C df --banana -B applepie README.md 
df: unrecognized option '--banana'
Try 'df --help' for more information.
[$? = 1]

So I suggest we simply ignore this behavior of GNU du, in favor of consistency. Also, I really hope nobody relies on this weird behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants