Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login
-h –Help -help Help –? –? (blog.craftyguy.net) similar stories update story
2 points by todsacerdoti | karma 157974 | avg karma 11.55 2022-04-11 12:11:22 | hide | past | favorite | 241 comments



view as:

The list is probably ignoring

    man foo
    apropos foo
    Info foo
;-)

Fun aside, I think -h/--help is nowadays the most widespread and accepted version in Linux/Unix-Land. A good CLI argument parser accepts both variants.


I always default to “man foo”, because of the occasional tool that when presented with -h or --help creates a file with that name; even if there’s no manpage, “man foo” will never have any undesired side effects.

Nearly every tool does have a manpage (even a basic one) thanks to Debian’s manpage policy: “Each program, utility, and function should have an associated manual page included in the same package or a dependency.… If no manual page is available, this is considered as a bug and should be reported to the Debian Bug Tracking System.”

The rare times I encounter a command-line tool that has no manpage, I’ll sometimes write one and contribute it upstream.

Of course some programs have a useless manpage that points to info. Thankfully that is pretty much limited to GNU tools which I’m lucky enough to not have to use very often.


There is the occasion where the manpage is useless compared to the help or the website docs. For example, the ironic 'man doxygen'.

Or the man page for OpenSSL's config, which actually has many of the options in the man pages for `req`, `x509`, and `ca`.

Hey, at least this doesn't create a file:

  shutdown -h

> Fun aside, I think -h/--help is nowadays the most widespread and accepted version in Linux/Unix-Land

The most notable exception (to me) among modern tooling is the `aws` cli, which parses help as a subcommand. And if you try `--help` it just gives you an `Unkown option` response.

I'm mildly amused by the need to reserve a little bit of brain-space for the ways to ask cli tooling for help


It would be easy for the authors of this tool to fix this behaviour. Checkout `git --help` vs `git help`, both versions work. That's just being nice to the user.

/?

/help

man $command

Can someone remind me what tool I use to convert markdown to man pages? Even better, anyone have a good way to embed a man page into my README?

Try pandoc [1]. You can convert back and forth between manpage and Markdown with it.

[1] https://pandoc.org/index.html


And also a few other formats. Wanna convert LaTeX to Black Speech? No problem! Use pandoc!

Mandoc, the default manpage formatter on OpenBSD, FreeBSD, NetBSD, macOS, and some Linuxes (as well as web frontends like manpages.debian.org and man.archlinux.org), can convert manpages to Markdown, or to HTML directly: https://mandoc.bsd.lv/man/mandoc.1.html#Markdown_Output

Or "help command" in powershell world. But applies to powershell cmdlets/functions only.

Edit: I just checked on windows, man is actually alias for help in PowerShell :)


Watch out for bloggers: they tend to make stuff up.

There are no "Posix long options" and therefore a "Posix-compliant" argument parser will not handle them just fine.

Long options set off using two dashes were popularized by the GNU utilities.

POSIX describes a getopt C library function and a getopts utility command. Neither of them specify any requirements for long options. They will not parse long options "just fine"; not without extensions for it.

In the GNU C library (and compatibles), there is a getopt_long function that supports long options; there is no attempt made to extend the POSIX getopt to handle long options.

POSIX does not have a help option convention: -h is not consistently a help option. The "Utility Syntax Guidelines" makes numerous recommendations about options; no mention is made of anything resembling long options, or that if there is a help option, it should have such and such name.

I don't know of any utility for which POSIX requires some kind of help option; it describes only the man command.


I feel the same when they talk about UNIX, but are actually describing GNU/Linux.

GNU/Linux == GNU is not Unix (even) over Linux.

:)


I usually refer to these as "GNU-style arguments", whether or not that's the correct terminology. The fact that Go-based utilities tend to use the `-option` style (with a single hyphen) still bothers me.

And since the article is using podman as an example: podman does have a manpage. The actual standard way of getting documentation on utilities, man podman, works just fine.

I think man pages tend to be more heavyweight than people sometimes; if I just want to see a few of the most common options to copy, it's a lot easier to have a few lines just printed out rather than having to crawl through potentially dozens of pages being piped to `less` and then open a second terminal pane if I want to look at it while I'm typing my command.

Put another way, I think `--help` is basically the CLI equivalent of generated API docs, whereas manpages are like long-form prose documentation. While you can get by with just one of them, the experience is going to be worse for certain use cases, and generally for anything beyond a certain level of complexity, your users will be better off if you provide both.


Downvoted because You can correct the article without making it personal

This is overly pedantic. The point is that people using POSIX (i.e. Unix-like) systems expect -h or --help to work, as a matter of convention. What the letter of POSIX-the-standard says doesn't really matter to most people.

But it’s not overly pedantic. POSIX is literally a formal standard, and that standard does not provide a mechanism for long options. Other “POSIX (i.e. Unix-like) systems” like the BSDs do not generally use long options, nor do they generally support -h as a “help” flag.

What you’re describing as a POSIX convention is really a GNU convention. But the world of POSIX consists of more than just GNU. So the grandparent post is correct.


POSIX is a legacy “formal standard”. The two biggest players by far of the Unix branch (Linux and MacOS) both implement it losely.

The POSIX strictness battle have been lost more than two decades ago. Behaving as if it did not, is overly pedantic.


A far more egregious error is pretending that -h/--help is some sort of universally implemented or agreed upon practice among command-line tools.

Large, complex code written in C that has a wide API footprint will work with little or no modification among systems like GNU/Linux, Solaris and Mac OS.

The specification is online and people use it when coding, refer to it it in discussions and when filing bug reports.

2018 edition: https://pubs.opengroup.org/onlinepubs/9699919799.2018edition...

It's been my experience that the maintainers of major FOSS projects take it seriously when something is reported as being at odds with POSIX.

I don't remember any recent "POSIX strictness battle"; you didn't just make that up, did you?

There was as struggle starting in the 1980's to deal with incompatibilities among large numbers of vendor-specific derivatives of Unix that were cropping up everywhere. Unix brand incompatibilities negatively affected the users, who wanted their programs (and skills) to transfer. That is more ancient history. In retrospect, it looks like the standardization effort was broadly successful.

POSIX is not exactly standing still; it has been amassing new interfaces, and vendors adapt them as specified.

When I started coding in Unix, gethostbyname was the way to resolve DNS; now you have getaddrinfo, which is more generic and can give you IPv6 and IPv4 results in the same call. Even in basic Unix functionality, there are new features: for instance, various "at" functions, like openat: open a file relative to a specified directory descriptor, rather than the current working directory. POSIX specified threads that work everywhere, shared memory that works everywhere and other things.

There is rather a struggle between "use latest stuff in POSIX" versus "have code work on older systems".

But, overall, POSIX is a huge relief.

POSIX is a big reason why you can take code written using Glibc and get it running on Musl. Or on Cygwin.

An alternative C library that has Glibc compatibility as its goal would be a lot more difficult to develop if it had to be based entirely on reverse engineering Glibc. The Glibc documentation isn't complete enough. (And, doh, that's because it expects you to refer to POSIX for the details.)


https://www.freebsd.org/cgi/man.cgi?getopt_long(3)

> HISTORY

> The getopt_long() and getopt_long_only() functions first appeared in the GNU libiberty library. The first BSD implementation of getopt_long() appeared in NetBSD 1.5, the first BSD implementation of getopt_long_only() in OpenBSD 3.3. FreeBSD first included getopt_long() in FreeBSD 5.0, getopt_long_only() in FreeBSD 5.2.

So the parsing support is there. And it is used, e.g. tar aka bsdtar:

https://www.freebsd.org/cgi/man.cgi?tar(1)

So long options were popularized by GNU but have since become common across different POSIX operating systems.


> So the parsing support is there. And it is used, e.g. tar

Yes, the parsing support is there, so software written in the GNU style does build and run correctly on BSD systems. But although you bring up tar (a command that is well known for its unusual and unconventional flag handling), it is generally the case that commands on BSD operating systems do not use long options.

Representative examples of prominent 21st century BSD software that do not use long options:

mandoc: https://mandoc.bsd.lv/man/mandoc.1.html

jail: https://www.freebsd.org/cgi/man.cgi?jail(8)

zfs: https://www.freebsd.org/cgi/man.cgi?zfs(8)

acme-client: https://man.openbsd.org/acme-client.1

signify: https://man.openbsd.org/signify.1

doas: https://man.openbsd.org/doas.1

smtpd: https://man.openbsd.org/smtpd.8

And of course old classics like ssh: https://man.openbsd.org/ssh.1

kazinator’s point, that there is no POSIX convention of using -h for help, is correct. That convention came from GNU, and while the idea has spread due to GNU’s influence, there are other prominent schools of thought in the POSIX or Unix-like ecosystem. I would certainly not agree that long options are the common case on BSD systems.


> ???? I have no idea where these came from, but my guess is that they are migrants from the wild west Windows-land, where I assume the shell won't try to expand ? into anything. Using these options will cause problems for anyone using common shells like bash, zsh, others. Don't do it.

They come from getopt() returning '?' for any unknown option, which usually ends up being the default case in your switch, but could be '?' to be explicit.


The bit about help as a subcommand and having to edit it out in a cumbersome way really hits home.

I'm looking at you, otherwise-excellent wp-cli. :-)


You need to discover either emacs or vim shortcuts for bash. I can't imagine living without `set -o vi`

At least in bash, just run

    ^help^^
Which will rerun the previous command but substitute "help" with "" (nothing).

It is in the nature of bash that you can go a decade without ever figuring something out only to have your life changed by a random comment on the internet.

So thank you. That changes everything!


:D I have been on the receiving end enough times that I am very very happy to have passed it on this time.

Is there a shortcut to reuse the result of the last command? “which java => ll $(!!)”, but the “!!” reexecutes the last command, I’d like something which doesn’t.

I'm not personally aware of a way to do that. When I need to do that I do indeed just run $(!!)

This is amazing! I don't think I'll use it for help (up-arrow, ctrl+w is fewer keystrokes), but I can think of many other situations where I want to substitute one word of a very long command and didn't realize it could be this easy

I think

  ^help^
does the same thing. The bash manual says ^string1^string2^ is equivalent to

  !!:s/string1/string2/
where / can be any delimiter, and the "final delimiter is optional if it is the last character of the event line." So, not so surprising that the third ^ is optional too.

TIL: In either of these forms, if string1 is empty, it is set to the last string1, or, "if no previous history substitutions took place, the last string in a !?string[?] search." E.g.

  $ echo foofoo
  foofoo
  $ ^foo^
  echo foo
  foo
  $ ^^bar
  echo bar
  bar

> is equivalent to

> !!:s/string1/string2/

I didn't know about this syntax either.

I thought I knew a bit of bash and it turns out I'm a novice after all this time. How fun.


The last point reminds me of the frustration of quitting the Python REPL.

I always forget the "version" switch. Is it '-v' or '--version' or '-version', everything's just a bit different and I can never remember what needs what to tell me its version.

[edited to add] As others have reminded me, there's also simply 'version'


I automatically assume `-v` is short for `--verbose` rather than `--version`, and always type out the latter.

I don't know but I always expect -V for verbose, and -v for version. However, I do acknowledge its not consistent :(

And not to leave out `go version`...

Everything uses --version, except `java -version`.

Except Java 17. Java 17 went to `java --version`. And `java -version` doesn’t work anymore (Yes I jumped from Java 8 to 17, but most people did).


And (e.g.) OpenSSL IS `openssl version`, with no dashes at all.

To be fair, when deciding how to implement CLI options, it's probably advisable to run as far away as you can from drawing any sort of inspiration from openssl. Even git looks like a paragon of UX compared to the openssl CLI.

You don't think that -text -noout is an intuitive way to output something as text?

mawk is the worst, which, given the article's claim about POSIX, is ironic, because mawk is POSIX-compliant.

  $ mawk --version
  mawk: not an option: --version
  $ mawk --help
  mawk: not an option: --help
  $ mawk -W version
  mawk 1.3.4 20200120
  Copyright 2008-2019,2020, Thomas E. Dickey
  Copyright 1991-1996,2014, Michael D. Brennan

  random-funcs:       srandom/random
  regex-funcs:        internal
  compiled limits:
  sprintf buffer      8192
  maximum-integer     2147483647
And mawk is (was in 16.04 at least) the default version of awk on Ubuntu. How is the user supposed to know this magic incantation? ¯\_(?)_/¯

To be fair, I can see this coming out of a strict reading of POSIX: it doesn’t say a single word about GNU-style long options (though there is an implied hole where they can fit), but explicitly leaves -W with an argument as a place for implementation-defined crufties when passed to Awk (I haven’t the slightest idea why).

(Honestly I’d rather not have the convention of programs themselves handling this at all and instead have this be `ident awk` or similar, but I understand this is not going to happen.)


I can only imagine that the "w" stands for "what the hell do I need to pass this thing to get it to tell me something useful"

When development on Java started in 1991, double-dash long options weren’t as prevalent as they are today.

-version still works:

  $ java -version
  openjdk version "18" 2022-03-22
  OpenJDK Runtime Environment Temurin-18+36 (build 18+36)
  OpenJDK 64-Bit Server VM Temurin-18+36 (build 18+36, mixed mode, sharing)

I think at one point the canonical approach may even have been:

java -D-version


I laugh at verbose options that are:

-v for basic verbose

-vv for more

-vvv for even more

-vvvv oh come on you've got to be kidding

-vvvvv nope, they're not kidding


I keep hoping someone will do this with -v², -v³, and so on.

Where the base value is two and -v³ is a shortcut for -vvvvvvvv? Because it wouldn't work with a base of one (1³=1).

Just assessing expectations because I do like the idea and would implement it (in addition to the expected way) next time it comes up


In my mind, -v³ would be the same as -vvv, and -v4 for -vvvv, and on and on.

I suppose you could really take it to some absurd level with -v¹° for -vvvvvvvvvv


The v is log scale, which does make some sense in terms of output volume. ;)

Ah, but you'd have to error on any even power, since of course a negative squared is positive, thus -v^2 would be v^2 and without the dash you can't be sure it's a switch.

There's an easy solution to this: just use i for even exponents.

So (-iv)² = -vv and once you've escaped the brackets in bash all is good.

I think we're on to something here....


Nah exponents have higher precedence than signs, it gets annoying otherwise.

  -vv ? -w
  -vvvv ? -ww
Just a joke :)

And yet… now I am deeply wishing for this. :-)

-w should be equivalent to -uu surely!

Not in France ;)

Well usually you can use -vvvv -> -vv -vv so if you make your font size small enough that vv looks like a w..

I absolutely hate this convention. Not only is there often very little documentation about what exactly gets added in for each verbosity level, making me guess randomly and then maybe binary search to find what I need with minimal noise, its basically impossible for me to differentiate repeated characters beyond 4 without using a cursor to step though them. I don't have any opposition to fine-grained log levels, but geez, just make it `-v [VERBOSITY (default 1)]` or something sane like that.

I went through this ritual almost every time:

    $ java --version
    Unrecognized option: --version
    $ java -v
    Unrecognized option: -v
    $ java -version
    openjdk version "1.8.0_312"
Looks like this was fixed in JDK 11.

But Java isn't as sadistic as Go lang:

    $ go --version
    [scrolls off screen]
    $ go --version | less
    [scrolls off screen]
    $ go --version 2>&1 | less
    [search for 'version' command]
    $ go version
    go version go1.17.2 linux/amd64

Related: my feeble attempt at adding -h and --help to go subcommands: https://gist.github.com/MawKKe/485ad4ce21223309d2e90713f3b9b...

(might be really buggy, let me know)


don't forget grep -v:

"-v, --invert-match"


This one is actually really interesting! I would guess that it comes from electrical engineering, and specifically the signal processing side of things where filters happen. One option for filters are “notch filters” [1], and the letter “v” looks like a notch. So just think of “notching-out” a signal when you’re trying to remove something from your grip results.

[1] https://en.wikipedia.org/wiki/Band-stop_filter


Might just be that i was taken for case insensitive.

62 characters is not a lot for tools that have a lot of settings.

In the case of tools like grep, the settings are really more of a command vocabulary, and should rightly be written in their own language in a script file, like sed and awk, but grep makes some especially commonly needed ops available as a simpler command with switches for convenience. And that results in some seemingly arcane and inconsistent commandlines.

Defining how to search for something is just not a simple 2 or 3 options covers it kind of job.

By contrast, another tool with the same problem but clearly originated from a different starting idea is 'find'. It also has to have essentially a vocabulary to express your intentions in composed sentences, and it ends up with a mix of switches and words.


I'd guess that it's probably just that `-i` and `-n` were used for other options, and `-v` is the next letter and a fairly prominent sound in the word.

Perhaps it was simply an available letter, as saghm said, but I've always imagined that at least part of the origin story is that it's a mnemonic for "invert" or "negative".

Don't forget the capital 'V' option, e.g. `python3 -V`

I usually assume that lower-case 'v' is for verbose.


...which is often confused with the switch for verbose

I tend to dedicate -v for version data in my apps, and use a -d(ebug) flag for more verbose logging. Or even follow the VERBOSE env var convention.

With some apps it's damn near impossible to query the version, especially cross platform. I used to manage a database of that syntax with a tool called "specs".


-d is for daemon mode (never default to this)

-p is for PID file

-l is for log file

-v is for version

-L is for verbosity level (e.g.: -L debug)

-c is for config file (where all the other options may be specified instead)

-h is for help

The rest are context-specific.


-c is often command

-f can be for configuration file as well (see: apache httpd, mongod, and sshd)

> Honestly, in practice, I've seen many tools that support -help also allow --help and -h for those who have the muscle memory reflex for those, so it's not nearly as problematic.

  $ javac --help
  javac: invalid flag: --help
  Usage: javac <options> <source files>
  use -help for a list of possible options
:-(

Using double -- for long named flags is a GNU-ism. Java came from Sun and so prefers the single dashes.

But "-help" is just "-h -e -l -p" ...

Which is also a gnuism

That's my point - "-help" violates the gnu standard.

That's his point, Sun has nothing to do with Gnu so they are not bound to their "standards".

the point was that that gnu is not a universal standard

“-help” being equivalent to “-h -e -l -p” is not a GNUism. It’s described by POSIX. If a utility takes the options “-a” and “-o something” and uses POSIX getopt(), then these are all equivalent:

    cmd -ao arg path path
    cmd -a -o arg path path
    cmd -o arg -a path path
    cmd -a -o arg -- path path
    cmd -a -oarg path path
    cmd -aoarg path path

A long time ago I filed a bug with Sun about inconsistent flags on the JDK tooling. As I recall it they fixed the sole specific example that I cited instead of reviewing them all...

Ooh, I think this might have been the one (at least the mention of rmi and MS style paths would be consistent with what I recall working on at the time):

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=5083924


the clever way to parse `-help` is to treat it as multiple options, but design your argument handler so that the `help` handler short-circuits and doesn't do anything except output help text and exit (i.e. it reads '-h' then calls the help handler and exits, doesn't matter if -e isn't a valid option).

Wouldn't that make it awkward to combine help with any other option? I guess that's an edge case, but still...

Most commands IME will have this short-circuit behavior

$ cmd --with -a --lot -of --options

(fails)

$ cmd --with -a --lot -of --options --help

(behaves as if --help was the only option)

From a terminal perspective, up-arrow + space + -h is often the fewest keystrokes to get what I want


Whenever I do `cmd -h` or `cmd --help`, and the command fails and asks me to type something else, I always find this a very helpful hint that cmd’s authors don’t have respect for conventions, and that I should be cautious with my expectations from then on.

I agree, but I dunno maybe this is more new school than I realize. I'm willing to accept the possibility that other people have been exposed to conventions I haven't. On my personal projects I stick to this convention though, it just feels like the right thing to do.

same for `cmd -v` `cmd --version`

The first one is verbose, not version, though? Not sure if you're used to a set of utilities that doesn't intersect the ones I'm used to where -v is version. I've seen -V, though.

And then there's grep


I agree that -V is more common. I have used a few things that use -v for version though (I think `ruby` does, which led to some confusion for me the first time I tried to pass that to `python` and instead of getting the version number found myself in a more chatty than normal python shell).

Defacto short switch for version is "-V". "-v" is verbose.

As is quite clear in this thread, there really is no unified way of doing things.

Uppercase switches also strikes me as not very intuitive, either you need to look at the help page or you have to have the same mindset as the developer.

And still, the distinction between lowercase and uppercase switches are not easy to remember.

For the power user though it makes sense.


The cat command is rather infamous for using -v to mean “visual” (as in, convert invisible characters to something visible).

But the infamy is not that it used -v for something other than “version”—I doubt that convention existed in 1983, when the complaint was made—but rather that it was a sign of the ever-growing complexity of specific Unix tools at the expense of the harmony of the whole system.

See “Program design in the UNIX environment,” by Rob Pike and Brian Kernighan, USENIX 1983: http://harmful.cat-v.org/cat-v/


Trouble is that some competing approaches appeared around the same time in history and what is convention depends on what you happened to be exposed to.

Honest question: the BSDs adopted getoptlong() 20 years ago[0], what are people being exposed to that uses -single-dash-long-options?[1]

Or were you referring to older utilities/actual unix times?

[0] https://www.freebsd.org/cgi/man.cgi?query=getopt_long&sektio... [1] I mean, there's oddities such as openssl(1) but those seem a minority on every platform


> what are people being exposed to that uses -single-dash-long-options?

Go's 'flag' package -- although double-dash is silently accepted on the command line.

The deeper issue with 'flag' is that it rejects the BSD convention of a short/long option pair having guaranteed equivalent semantics e.g. -h/--help. The library just won't let the programmer create such a pair by means of its standard functions.


> Go's 'flag' package

Which uses the Plan 9 convention; the system the Go creators were exposed to. A good example of competing conventions of the past rearing itself in modern tools.


Ocaml is notorious for having CLIs that use longform options with a single dash. It’s infuriating. So it would be -help in this example

A few of my college courses used OCaml, and it had lots of conventions like this that I found somewhat odd. If I remember correctly, exceptions (which were not used that often from what I could tell due to preferences for handling errors in a more algebraic manner) are named with casing like `Not_found`, which I don't even know the name for (maybe "capitalized snake-case?), I assume to try to make them resemble the capitalization scheme that sentences use. I also remember finding it quite strange to read types annotated with a space before the colon (e.g. `let x : int in`); a friend told me that this was due to OCaml's authors being French, which unlike English puts spaces in front of colons in prose. Combined with the fact that we were taught only a subset of the language (we never once learned how to use the object system for which the "O" was put in OCaml), and we were processed provided with pre-written build files for projects and not taught much how how to use the build tools, writing OCaml always felt somewhat surreal for me. Overall though, I did learn a lot from those classes, and I think it was a good choice for teaching the concepts the courses were intended to cover (especially the compilers course, which in retrospect I would have found much more tedious if course was taught in C or Java or something).

> I also remember finding it quite strange to read types annotated with a space before the colon (e.g. `let x : int in`); a friend told me that this was due to OCaml's authors being French, which unlike English puts spaces in front of colons in prose.

Maybe, but I find it more likely that they just copied math notation. In mathematics (broadly, not just theoretical CS, also analysis), the type of something is indicated with an infix `:`, like `f : A -> B` is a function from A to B. This colon conventionally has equal spacing on both sides, like a regular infix operator.


That's possible as well. I have no idea about the accuracy of my friend's claim, which is why I relayed it as hearsay rather than stating it as a fact I was sure about.

A lot of the decisions in OCaml seem related to the French language, which adds a space before the : (unlike in english).

There's the "Thing of int" weirdness also


OCaml exception constructors are just term constructors in the open sum type `exn`. In OCaml, to distinguish constructors from bound variables, constructors must begin with a capital letter. Thus `let Foo = 4;;` is an error.

That doesn't explain why they couldn't have used `Not_Found` or `NotFound` instead.

sometimes it's because the software existed before the conventions. Such is the case for Xorg.

> This pattern is cumbersome to deal with in practice, especially in tools that use subcommands. Instead of typing foo bar -h to get help, you have to move the cursor between foo and bar to insert help: foo help bar in order to get help about the bar subcommand. Then, once you presumably know how to use it, up-arrow, remove help from between the tool and subcommand, move to the end of the line, and continue on.

This is not a pain if you are using the default readline keybindings (which ape those of Emacs): up arrow, M-b to move back one word, type 'help ', hit RET; for the next bit, up arrow, M-b M-b to move back two words (to the beginning of 'help'), M-d to delete forward one word, C-e to go to the end of the line and you're done. No doubt it's similarly easy using the vi keybindings.

That sounds complex, but really it's second nature.

> As in the case of podman above, if you know your user is asking for help, show them the damn help.

The issue there is that it doesn't know the user is asking for help, because the way one asks for help with podman is with --help; -h is meaningless to podman. Note that -h isn't always the flag for help; just off the top of my head, in several command-line tools it is the flag for human-readable file sizes.


> No doubt it's similarly easy using the vi keybindings.

I'd do kbihelp for the first and k2bdwA for the second.


or you can use C-x C-e to edit the command in $EDITOR

Ironically when I tried to run that in vterm in emacs it triggered an Emacs command which failed.

I hate when a program tells me what I have to do. I always think "damn it program, if you know what to do, just do it already. I say what to do, and you do it".

For example when terraform tells me to run "terraform init", as if actually typing the letters on the keyboard had any benefit...


Same thing with Python:

>>> help

Type help() for interactive help, or help(object) for help about object.

>>> exit

Use exit() or Ctrl-D (i.e. EOF) to exit

If you know what I'm trying to do, then just do it!


  >>> print "hi"
  SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
I would be in favor of that for this one!

That was the behavior in python2 and it was changed for good reason.

If you do want this, consider ipython as your Python REPL.

https://ipython.readthedocs.io/en/stable/interactive/magics....


Yes, hence the semi-joke. But I actually do think it was a good feature and a bad idea to remove it.

Isn't this due to some REPL-constraints or not wanting to break the way the language works? Maybe there's no way to evaluate the "exit" and "help" objects replaced by "exit()" and "help()", and that making exceptions would clutter the code. Not sure the reasoning behind it, but that's what it seems.

> not wanting to break the way the language works

This is the reason. "help" and "exit" (as well as "quit") are perfectly cromulent variable names in Python. So the REPL does the best possible thing, i.e., try and evaluate the expression and shoot a message if it fails. Case in point:

    >>> help = "hi"
    >>> help
    "hi"
    >>> del help
    >>> help
    Type help() for interactive help, or help(object) for help about object.

Why not:

    - check if a variable called "help" is in scope
    - if not, call help().
    - otherwise, print its value.

Because then when there IS a variable, the help command you learned will not work.

I think anyone crying and baffled about this is fundamentally not well suited to programming. This sort of logical problem should be intuitive.

The seeming irrationality of the special case behavior is just something funny to make your mom laugh, not something that's actually illogical or inconsistent or stupid.


What if you have defined a "help()" function though?

REPL should be as dumb as possible. That's a feature, not a bug.


There’s nothing special about those variables besides them being builtins. Those messages are actually just the __repr__ for each.

You could make `exit` quit the application when __repr__ is called.

Not sure if this is a good idea however.


It doesn't know what you're trying to do, it can just make a best-effort guess, which may be wrong. Maybe you are deep inside a session, trying to inspect a variable or function called `exit` that just doesn't happen to be in scope like you expect? Exiting the process at that point could be terrible and the impact of the lost state exceed the lifetime-accumulated lost seconds that would have been saved by being "helpful".

If you really want this, consider using ipython with %autocall as your Python REPL.

https://ipython.readthedocs.io/en/stable/interactive/magics....


It's worse:

    Type "help", "copyright", "credits" or "license()" for more information.
    >>> help
    Type help() for interactive help, or help(object) for help about object.
    >>>
Python tells you to type "help", but when you do it turns out that that doesn't do much. I get it, they want to make the distinction between help() and help(object), but I feel that could have done a bit more friendly.

My "favorite" one of those is Mercurial's error when you use a subcommand that you need to enable an extension for. Not only does it know the subcommand is valid, it also tells you which extension to enable. If it's gone all that way, why not enable the extension automatically?

I have been trying to google this concept of confusion for years. Finally, an article where someone has had the same thought as me about the consistency. This has been one of those things that's impossible to search for because everything routes into a technical syntax discussion (like a MAN summary page) instead.

Don't forget /?

The only place I've seen this is windows world where /arg and -arg are the same thing. Don't ask me how this came about.

DOS, where /arg was the way

Which it got from CP/M, which borrowed the idiom from VMS.

They originally used - but IBM wanted /

IIRC, it's up to the application whether they handle /arg and -arg forms. They might just as well not support the latter.

-hh is what a major app at work requires. Engineering indeed provides room for creativity.

I want to throw out there that in addition to these parameters and how you call them in different ways, the order of operations for them is also very frustrating.

FFMPEG comes to mind immediately as an example. Essentially, you call ffmpeg to convert media1 with specs and provide media2 as an output for it. I'm understanding that THIS order matters so you're applying arguments onto the input instead of trying to do something on the output for some reason.

Where it gets confusing, though, is if you want to resize and crop an image for example. You may end up with different results depending on the order you specify these operations.

Maybe this particular use case makes sense because resizing and cropping hard-coded coordinates could be confusing. However, other operations that seem like they shouldn't interfere with each other sometimes do.

It would be nice to see some type of handling so there isn't this type of confusion. Perhaps some type of --override command, otherwise default to a consistent output regardless of order.

In contrast, I can't think of any issue I've had with "ls". I like that -l -a -t -r can be combined into -latr, but it does make learning the terminal very confusing for beginners when this isn't always supported or consistent in other programs.


> Where it gets confusing, though, is if you want to resize and crop an image for example. You may end up with different results depending on the order you specify these operations.

Could you clarify, what's confusing about it? The operations in ffmpeg are sequential, unless you use advanced chaining capabilities. If you look at a crop as a substraction, and at a resampling as a multiplication, it becomes evident, how the order affects the result.

(24 - 4) * 0.25 = 5 24 * 0.25 - 4 = 2


> As in the case of podman above, if you know your user is asking for help, show them the damn help.

Since (as other comments say) you can never know for sure that the user is asking for helo, the only sane way to actually implement this is to show the "usage" message on every incorrect invocation of the command.

This has two drawbacks, however:

* It makes the output of an incorrect invocation much longer. Personally, I prefer the 2-line output approach (1 line for the error, 1 explaining how to ask for help)

* You still need to have an explicit help command, because I sure as hell don't want to craft an intentionally incorrect invocation every time I want to see the usage message.

My 2 cents: just use "--help/-h" or a "help" subcommand. They are by large the most popular ways to check out usage, no need to be creative here.


This post resonated with me and the inconsistencies certainly don’t add to the already bad discoverability of CLI arguments. Personally, I find using -h/—-help the most sane way (YMMV).

Learn to read manuals, not blogs or Q&A sites.

POSIX.1-2017 https://pubs.opengroup.org/onlinepubs/9699919799/

GNU Manuals Online https://www.gnu.org/manual/

Linux man pages online https://man7.org/linux/man-pages/index.html

Ubuntu Manpage Repository https://manpages.ubuntu.com

Reading UNIX Manual Pages | Apple Developer Documentation https://developer.apple.com/documentation/os/reading_unix_ma...

Windows Commands https://docs.microsoft.com/en-us/windows-server/administrati...


Is or was -q ever used for help? Or is this a weird thing one of my coworkers started?

Some apps don't even provide a help menu. They may come with a man page.

And some come with dozens of man pages, several of which need to be combined to find the syntax allowed by certain commands (often also needing a help command)! OpenSSL is bad in this way.

"You: Hi! I won! Here's my ticket! Where do I collect my winnings?"

You think you are talking to the clerk that will initiate the payout but actually you are talking to the machine that made the draw.

When you try -h or --help then the result can be nice or not. In general the author gives quite a lot of pointers. However the docs are where it is at and that is from man or Help -> etc.

If the docs are provided and if you can't be arsed to read the docs then bugger off! Now this is where it gets tricky. Not all programmers are decent writers of docs nor are all potential consumers of docs decent readers.

Now OP is whittering on about incantations requesting help. They only demonstrate a few examples so eventually one of those incantations might work.

The important thing is to ensure that a request for help does one of two things: provide help or no op.


Abseil flag library has --help and --helpfull flag.

For a code base as large as Google's, using --helpfull to output every single flag that is defined in the libraries you depend on will output a huge wall of text and often not very useful.

I always had an idea to write a --helpful flag that will pipe --helpfull output to $PAGER. That's definitely more helpful than --helpfull.

https://abseil.io/docs/python/guides/flags#special-flags


I would prefer to (and do) just add the pipe myself. More often I pipe to grep.

If I’m looking for a specific flag, or trying to understand what a specific flag does, I prefer to pipe the --help output to grep:

    ./my_cli —-help | grep -C 2 —- —-someflag

I tend to avoid doing this, for reasons someone else described in a comment (https://news.ycombinator.com/item?id=30993390): some programs spit --help output to stdout, but others to stderr, so you wind up running it a second time as “my_cli --help 2>&1 | grep ...”.

In addition, if I don’t perfectly know what I’m searching for, I’ll often get the regular expression wrong. So I prefer to check the manpage first, since it’s a lot quicker to try different search strings in my pager than by repeatedly modifying my previous command string in the shell.


It took me a second to realize that this option was supposed to comprise of both the words "help" and "full". At first I was wondering if "helpfull" was a British spelling of "helpful" that I had somehow never come across below.

> Ah, the POSIX short/long help options

The long arguments are not in POSIX. They were invented by RMS having seen them in TOPS-20. (The short options come from Multics).

The other case ignored by the author is to print out a diagnostic plus help when there is a syntax error in the invocation. This works when the command arguments are few and simple, else the case cited (explain how to ask for help) is the right thing to do.

Single-dash long arguments are indeed generally bad.


how do you invent something by seeing it somewhere else? doesnt seeing it somewhere else mean it was invented somewhere else?

Ah, maybe “invent” is too strong a word but OTOH every invention is built on something beforehand (even the wheel presumably followed rolling something heavy over logs, presumably after making the connection about circular things rolling downhill etc…)

But long options are not so complicated an idea that “invent” might be too high falutin’.

Just for fun I’ll split hairs though: TOPS-20 (and VMS) basically only had “long” options (they could be a single character of course). CP/M and DOS got their arg syntax from TOPS-10 & RSTS but we never had TOPS-10 at MIT AI.

What RMS came up with was to have both long and short, to use two dashes to disambiguate from concatenated short options, and used the = syntax (which dd, at least, already used). Then bfox put command completion into readline, which definitely was inspired by TOPS-20 command completion (itself from TENEX).

Before that we had our own OS, ITS, and most programs didnt take options because the system didn’t really have a command line at all: instead of what is called a ‘shell’ in Multics (and copied by Unix) we just used the debugger. And of course lispms, where the whole concept of command line doesn’t make sense.

By 1984 there was one Unix machine, a VAX, in the lab but nobody used it (small word size, didn’t have much software, primitive development environment compared to what we were used to) which is why rms started using it to develop GNU.

Whew. More than I thought one could write on the topic!


didn't TOPS-20 just require you to type enough of an option/switch to /DISAMBIG it from any other potential conflicts?

Honestly I can’t remember if that was the case (though it vaguely sounds correct) or if you had to complete (was that tab?).

Now ELF is ubiquitous I wish the tab command completion were built into a section of the binary rather than being in sidecar files elsewhere in the filesystem, which is fragile.


i think tab would prompt you choices to enter next. possibly configurable. iirc this was all in a module that wasn't necessarily installed if your site couldn't spare the extra Ks of diskspace :)

Just have to buy another washing machine.

In the same vein, as an old unix dog, I'm very annoyed by golang's -help vs -h and --help. Given the pedigree of the creators, I really am quite puzzled as to why they took this approach. Is there some sort of injoke where -help meant -h[elp] which would therefore expand to e.g. -he, -hl, -hp, -hel, -hlp, -hep ad nauseum?



Is that so odd? The creators have a background that predate the (relatively recent - even more so when golang was created) GNU convention. A convention that is (or at least was) mostly prevalent on Linux anyway.

Personally, I'm puzzled when people act as if the GNU double dash convention is a universal standard.


-foo wasn't all that uncommon in Unix, especially before GNU. Do you remember command line options for oldschool X11 stuff? e.g. xterm -fn 7x13bold -geometry 80x32+10+50

There’s a special place in hell for those pushing long argument names with single hyphens.

One hyphen is for shorthand, two for long name.


Clang, swiftc, etc. would like a word with you... :)

(It bothers me too.)


-fpic is a single letter option, -f, followed by the parameter pic. Clang still uses two hyphens for long options including --help.

There are tons of options that start with -f and can't be decomposed in that way [1, e.g. -framework]. They are essentially atomic options with a loose naming convention.

[1] https://clang.llvm.org/docs/ClangCommandLineReference.html


Correct. You cannot use “ramework” as an argument to “-f”. Instead use two dashes and it is unambiguous.

It took me some thoughts to realize what you wanted to say, and you are incorrect: there is no single option `-f` in cc options! `-f` is just a common prefix of hundreds of independent options, like `-fsanitize=...` (which can't be used as `-f sanitize=...`). As I've iterated before, those prefixes mostly represent broad categories of options and not hard and fast rules: `-g` for debug, `-i` for directories, `-m` for target architectures, `-W` for warnings, and `-f` for virtually everything else.

But maybe we should talk about the lack of space character between the flag and the argument…

That's just how short options with arguments work in getopt POSIX land: '-oARG' is equivalent to '-o' 'ARG' just like '--option=ARG' is equivalent to '--option' 'ARG' (for GNU long options). This means that you cannot chain any other short options after one with an (optional) argument but otherwise does not cause any problems.

Yes not every Linux/unix arg parser conforms to posix, some require a space, others do not.

None

To be fair to Clang, the -arguments are inherited from GCC for compatibility (which perhaps inherited them from other CCs) and then extended from there in the most consistent way possible. Similarily, clang-cl supports cl.exe-style flags for drop-in compatibility.

If there are lots of long argument names and many of them are freqently used, there is not much point for shorthands though. Better to treat single-letter "shorthands" as their canonical names in that case (e.g. compilers). Of course you can still argue that all of them should have two hyphens.

Yes. Also for people who insist that you use —-help but won’t accept -h.

>$ footool --help

Unrecognized bar "--help", aborting!

Use: "footool help" to display usage information

>$ man footool

No manual entry for footool


Probably a typo but requiring `—-help` with em dash would be another level of evil.

The worst offenders are the ones who even put the logic in to let one know that they knew exactly what one meant, but instead of accepting it they purposely throw an error, and adding insult to injury, telling one what one should have provided.

Those people are psychopathic abusers, and for some bizarre reason seem to be drawn to computers. I haven't figured out why yet.


Like “exit” in the Python repl, Which,knowing perfectly well what you wanted to do, will bark back “use exit()”. And only now, decades later it’s actually being fixed, but you still have evil bastards complaining that it should not do what you expect.

Yes. git push does this.

No, that's just GNU.

Originally, yes. Now it's much more widespread, because it turned out to be a good idea to have consistent argument syntax.

> long argument names with single hyphens.

Also --long_options_with_snake_case


Might I caution you away from any tools built with the Abseil flags library.

Looks like a leaky abstraction, in which a negligible amount of time saved in development (by mapping command line options directly to identifiers) results in UX woes.

One of the many reasons Hashicorp tools are braindead.

For whatever reason, the Java tools have had these from the beginning. It's rubbish but you get used to it. More recently, they have been using double hyphens for long flags. So now you don't even know which it will be! And of course, there are extra options hidden under -XX. And flags which take arguments use inconsistent separators. So a command line might look like this:

  java -agentpath:/opt/agent.jar --module-path /opt/modules -XX:HeapDumpPath=/tmp/heapdumps

> For whatever reason, the Java tools have had these from the beginning.

The double hyphen thing was standardised by the GNU project.

James Gosling didn't like GNU (I think based on something that happened in the Lisp days?).


Funnily enough, find(1), one of the oldest Unix tools to still be somewhat actively used, had those from the very beginning. Although, arguably, find(1) can be considered an interpreter of a language of its own, like sed(1) and awk(1), as opposed to a utility that accepts flags.

See the Unix v5 man page source: https://github.com/aap/unixman/blob/master/v5man/man1/find.1. (If anyone has a link where those are rendered, please let me know.)


According to Dennis Ritchie, find(1) was developed by a different group at Bell Labs which explains the difference in style. “…We were somewhat put off by the syntax of their things. However, they were clearly quite useful, and they were accepted.”

http://doc.cat-v.org/unix/find-history


Open a terminal in a directory;

Find Files $ find|sort|egrep -i 'file.name'

Find Text $ find|sort|egrep -iR 'text.in.files'


"It came from NJ" was a pejorative at Sun. Like, if you were staring at some awful piece of code in Solaris, and you were like, "who wrote this??" and asked around, and the answer you got was "it came from New Jersey", that meant it was part of SVR4.

I guess you mean all the developers of the Go Programming Language deserve a special place in hell ?

Why do I have to laboriously type two hypens for a readable option ? Causes finger pain especially when you have a large number of options.


> Why do I have to laboriously type two hypens for a readable option?

Suppose you have a CLI app that supports the following parameters:

  -e extrapolate your foos
  -h highlight your bars
  -l line up your bazs
  -p print the aforementioned as they're being processed
So you might run the CLI as:

  cli -ep
  cli -hp
  cli -ehp
  cli -lp
  # a bunch of other combinations, including
  cli -ehlp
  # but since the order doesn't matter, also
  cli -help
Do you see why that might be a problem with the short parameters?

Now, most applications would reserve -h for help, so instead you'd still end up with the following:

  cli -help
  # so, the user wants to
  # -h get help information
  # -e extrapolate your foos
  # -l line up your bazs
  # -p print the aforementioned as they're being processed
which does not make a lot of sense. That's why you'd normally have something like:

  -e --extrapolate extrapolate your foos
  -h --help get help information
  -i --highlight (-i seems close enough) highlight your bars
  -l --line line up your bazs
  -p --print print the aforementioned as they're being processed (though this is just an example, a lot of packages also use -v --verbose)
So then there's no such confusion:

  cli -ielp # makes sense, a bunch of commands
  cli -help # still doesn't make (much) sense, help shorthand mixed in with arguments for data processing
  cli -h # makes sense, short hand for --help
  cli --help # verbose help command
  cli --highlight --extrapolate --line --print # also makes sense, just more verbose

I don't get this. Why did you reserve '-h' for highlight in the first example ? And then you chose the long option form "-h/--help" to say the problem is now fixed. It seems an entirely artificial problem made by an originally bad choice. And has nothing to do with lack of double hyphens.

"go -h" is same as "go help".


> I don't get this. Why did you reserve '-h' for highlight in the first example ?

Well, for the most part i wanted to show that:

  cli -help
might actually be interpreted as 4 short arguments (grouped with -), instead 1 long argument (--), these are the same if you go by GNU conventions:

  cli -h -e -l -p
  cli -help
Thus using -help like you're offering doesn't make sense whether -h is for "help" or for "highlighting" (example of a fictional action that the CLI might support) or anything else. In practice you won't see many software packages reserving -h for anything but help, but -elp would be a stupid example.

To understand this better, consider the following in a case where the file you want to process is literally called "help" with no extension (which is valid):

     cli <ARGUMENTS> <FILE_TO_PROCESS>
  1) cli -h -e -l -p help # uses 4 arguments on a file called "help"
  2) cli -help help       # uses those same 4 arguments on a file called "help"
  3) cli help             # processes a file called "help" with no arguments
  4) cli -h               # invokes whatever is under -h, be it help/highlight or anything else
  5) cli --help           # the help argument, if present
  6) cli --highlight help # the highlight argument, if present, on a file called "help"
With what you're offering, options 1, 2 and 3 probably wouldn't do what you expect them to, unless you reject GNU semantics.

Ok, I see this specifically a problem with GNU option collapsing, overloading help and not returning an appropriate error for invalid usage when invalid options are passed to '-h'. Frankly, if I wanted to collapse lots of options, I would either make another option simply for that (or option concatenation option like '-c') or introduce sub-commands. Better design and more human-memorizable.

But thanks for detailed response. Upvoted for explanation. :).


The first rule of writing Go CLI tools that don’t drive users insane is to use “github.com/spf13/pflag” instead of the “flag” standard library package.

Rather annoyingly that is often the only third party dependency required…


Oh, if only I could upvote this more! And even more torture and suffering is reserved for those morons who use --long-options "because they are easy to remember".

The LSI MegaRAIDb proprietary command line tool, MegaCli, is guilty of this and several other transgressions...

I want -h -help --help and -? to all print the usage text. The fact that so many CLI tool programmers either don't realize that this is the right thing to do, or don't bother to do it, is just part and parcel of how user-hostile most programmers are.

I’m against lowercase -h for help (pretty common, but not universal, like in -h for human-readable sizes in GNU coreutils) for the same reason as lowercase -v for version (very rare, uppercase -V is more frequent, but the Lua interpreter does use lowercase): it hogs a valuable mnemonic for a case that doesn’t really need to allow for muscle memory to develop (the best motivation and use case for short options IMO): if you are reaching for help or the version number, you’re likely already out of the flow and are actively thinking about what you’re typing, and these options don’t need to combine with others anyway.

Allowing -? would be nice, even if only to make life easier for recent DOS/Windows expatriates, but for C programs there’s an unfortunate historical accident making this awkward: POSIX getopt(3) returns the next option character on success and a question mark on error. No reason it couldn’t return something else in principle, but realistically it’s not going to change at this point in history.


Needing to get info on command line flags is not only such a common thing but also a kind of recursive problem (you can't find out what flag to pass without being able to invoke the help text in the first place) that I'd argue it's the most valuable possible recipient of a single letter mnemonic. Having a universal and short way to print out the list of options seems way more beneficial than something like human-readables sizes, which only even makes sense for a certain subset of command line tools (what would it mean to invoke `python` or `docker` with a request for "human-readable sizes?).

If commands print out their help message, or even just tell you how to print out the help message, when given a bad flag, then you can use:

  foo --$(uuid)

> you can't find out what flag to pass without being able to invoke the help text in the first place

  man command
*ducks*

Man pages are not perfect, among other things because they are only useful as a quick skimmable reference for commands with a small amount of relatively simple knobs, but I do think that the tension you are referring to is best resolved by accessing the option reference through an out-of-band mechanism (even if it is actually stored in-band, such as when using the ancient ident(1) to retreive version strings).

> what would it mean to invoke `python` or `docker` with a request for "human-readable sizes"?

I will not deny my desire for a common glossary of short options (see the SysV / GNU coreutils delimited-text suite), but at the same time I don't think it's realistic for every option letter to have a single meaning throughout the whole of the system, which is how you seem to have interpreted my statement. I do think that being able to type -h instead of --help is less valuable than being able to not use a contrived second-choice letter for something else that really wants to be called -h.


Funnily enough, I commented elsewhere shortly after the one you responded to about man commands versus help text: https://news.ycombinator.com/item?id=30999162

I won't bother restating the whole thing here, but basically, having a giant wall of text dumped into a pager is not super ergonomic if you just want to look at a couple examples while typing. Man pages are definitely useful, but for a different type of thing.


I just experienced this scenario today with aurutils [0]. Perhaps I needed to reboot after building it, but it only gave me any insight into its syntax when I typed “aur” with no other flags.

[0] https://github.com/AladW/aurutils


This is part of the reason I only use long args in scripts... to make them more self-documenting and discoverable / less ambiguous. Takes a little more effort upfront, but no need to check man pages, help, etc for random single-char args later.

(This tip probably came from another HN user long ago.)


I hate the commands that pretend that the only way to bring up help is "--help" and that "-h" isn't anything. Just show the help text, you know "-h" means I want help.

Ah, another reminder of my ex-coworker who wrote a script that:

* operated on production data (rather than beta/pre-prod data, or failing if stage is not specified) by default * did not recognize `--help/-h` as flags, but would simply ignore them and continue to run

I'm not exactly happy in my role currently, but I'm a damn sight happier not having to deal with him anymore.


and then you launch from the command line into the app’s own console starting with > where no flags work and maybe informative commands are actually function names ending in ()

But no, maybe that doesnt work either


And then you encounter some ancient apps without GNU readline support (oracle sqlplus and mysql, I'm looking at both of you). No history support, cursor keys emit characters on the line, literal hell when trying to quickly fix remote database...

rlwrap [1] may be able to help

[1] https://github.com/hanslub42/rlwrap


I ran into this recently with the default sftp shell on macOS. Tab makes a tab character also. Very annoying.

Ahhh, and of course:

  $ foo -h | grep bar
  The
  …
  …
  entire
  …
  …
  usage
  …
  …
  message!
Never stop being you, Free Software, you lovable and quirky bunch of old coots.

I think this is because some tools print the usage message to stderr rather than stdout (ironically I couldn't find an example while typing up this reply). Try:

$ foo -h 2>&1 | grep bar


Thanks, but you’re explaining that my finger hurts because I hit it with a hammer when I’m complaining (in a kind hearted way, I hope!) that Free Software hammers have angled heads which skid off the nail sideways onto my finger.

  $ zfs -h | grep help
(Edit: ah, not a very fair example, and a topical one too :)

It's not just help. The example shows this

  $ podman -h
  Error: pflag: help requested
  See 'podman --help'
The program recognised the flag. But instead of running the intended functionality, it tells you to re-run it. And this maddening behaviour is pervasive. You already have the code processing this, you've coded the functionality to output "you wanted X, but typed Y" because apparently this is a common thing for people to do, why don't you just run X?

(Looking at `brew upgrade/update` in silent fury)


It appears that docker cli will also eventually remove the short option for help. Their reasoning for it is to avoid conflicts with args (eg hostname '-h') in certain subcommands.[0][1]

But I don't see why they couldn't leave the base command's short option alone-- the user intent of a bare "docker -h" (or "podman -h") seems obvious.

[0] https://docs.docker.com/engine/deprecated/#-h-shorthand-for-...

[1] https://github.com/docker/cli/issues/3249


The worst offenders are apps that do something even though you ask for --help.

Oh you asked for --help? No worries... I won't complain about an unknown argument nor will I complain about having no arguments at all! I'll just go ahead and do whatever I think you're asking for help about even (especially) if it's destructive!


same thing goes for -v -Version -version --version --v ?

"-?" is supported by apps that use GLib for option parsing:

> GOption will recognize the `--help`, `-?`, `--help-all` > and `--help-groupname` options * (where `groupname` is > the name of a #GOptionGroup)

Ref: https://gitlab.gnome.org/GNOME/glib/-/blob/main/glib/goption...

Looking at the Git history, it was recognized straight from the start, when GOption was introduced in 2004. No idea why they chose it, and if it was their own idea, or if they followed some existing convention from somewhere else...


/?

Another disturbing pattern I've noticed is that a lot of newer command-line programs refuse to have a proper man page. Instead, they put massive dumps of preformatted text behind one of those --help flags, which has several obvious issues. In the worst of cases, the text also uses colours, with no way to remove them without piping the output thru a sed filter.

From its earliest days, Unix has used a single hyphen to introduce command options or flags, like 'ls -l', which produces the long form directory listing, and 'cat -n', which numbers the lines that it outputs.

Every author of a command makes up the conventions for these flags. The shell processes the command line, invokes the command and passes the processed words to the command as arguments. While there are standard library routines for parsing these arguments, they don't have to be used and many original Unix commands would have been written with their own parsing code.

The oldest Unix commands like 'ls', 'cp', 'rm', and 'ps' mostly take single letter arguments. Authors often allowed such single letter arguments to be stacked up: 'ls -l' means list directory contents in long form while 'ls -r' means list directory in reverse alphabetic order and 'ls -lr', 'ls -l -r', and 'ls -r -l' mean all do the same thing, list the directory contents in long form in reverse alphabetic order.

It wasn't always the case, but by now, 'ls' has over 40 or 50 single character arguments so I find myself needing to check the man page for the less common ones. There are other quirks too. Both 'tar' and 'ps' accept arguments that don't have the dash. 'ps -a' does (almost) the same thing as 'ps a'. 'tar -xv' will extract an archive, verbosely, but so will 'tar xv'. The author of these ancient Unix commands just decided to parse the command line arguments this way.

What always bothered me was the use of full words instead of single character options introduced by a single dash. The 'find' command is one of these early Unix commands (introduced 44 years ago) that does this. "find /home/joe -name 'x*y' -print" outputs every file under directory /home/joe with a name starting with x and ending in y. This very useful command has a dizzying list of uses so the author made it easier to understand by using full words after the single dashes for elements on the command line. The recent versions of 'find' also take some single character flags: "find -d /home/joe -name 'x*y' -print" does almost the same thing as the previous example in this paragraph, but it descends into directories in a depth-first order.

Compilers, with there own complex set of command line flags, options, and arguments have long used their own, offbeat, interpretations of their command lines arguments.

Most Unix commands attempt to parse their command line arguments and if they couldn't, they would print out a few lines with a compact usage description. For example 'ps -Q' is not something that the 'ps' command understands so it produces:

    ps: illegal option -- Q
    usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
          [-g grp[,grp...]] [-u [uid,uid...]]
          [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
        ps [-L]
If this isn't enough help, one would check the man pages (with 'man ps'). I know that I saw commands written to use help when passed '-h' long ago, but around 1986 or so it wasn't common and often '-h' simply triggered the standard usage output because there was no option '-h'.

I find it hilarious that on Windows there are commands using Windows style options (ipconfig, robocopy) and Unix style options (netstat, tracert). That's probably part of the POSIX compliance. So the list of possible help options to try is even longer: "/?", "-?", "/h", "-h", "/help", "-help", and "--help". For most of the utilities distributed by MS "/?" works even if the command uses dash options, but third party utilities usually support only their "native" options.

    git /?: '/?' is not a git command. See 'git --help'.

    7z /?: Unsupported command

    psql /?: trying to connect
And for PowerShell cmdlets you should use "help Verb-Thing" or "help Verb-Thing --Online".

Just if the mess couldn't get any messier.


Legal | privacy