1

Many command line utilities accept long ("GNU style", according to [1]) options such as --version. To my surprise, truncated versions are often interpreted as the full option. For example, df from GNU Coreutils gives

user@computer ~ $ df --version
df (GNU coreutils) 8.32
Packaged by Gentoo (8.32-r1 (p0))
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Torbjorn Granlund, David MacKenzie, and Paul Eggert.

The same output is obtained by replacing --version with any of the truncated variants --v, --ve, --ver, --vers, --versi and --versio. However, when I add additional letters to the option, it suddenly realises that the option is invalid:

user@computer ~ $ df --versionn
df: unrecognized option '--versionn'
Try 'df --help' for more information.

Is this behaviour intentional? What is the reasoning is behind it? My understanding is that most utilities rely on getopts or getopt (or similar), so I have looked into their manpages for clues, but not found any explanation.

[1] E. S. Raymond. The Art of UNIX Programming. Pearson Education, Inc, 2004

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Mårten W
  • 119
  • 4
  • The parser is clearly matching unique strings. After `--v`, there is only 1 match, among the accepted options. `--versionn` is a different string entirely, and matches none of the accepted options. If you're curious, you could get the source for `df` and read it. – waltinator Nov 12 '21 at 23:31
  • @waltinator: This is not handled directly in ```df``` since it uses ```getopt_long```, but in any case, this does not tell me anything about the reasoning or design choice behind the behaviour. – Mårten W Nov 12 '21 at 23:36
  • @zevzek: Yes, apparently it is mentioned in ```man getopt``` and ```man 3 getopt```, but not ```man getopts```, which was the one I studied most closely. – Mårten W Nov 13 '21 at 13:49

2 Answers2

1

The point is to save typing. So for example you can type ls --col|less -R instead of having to spell out ls --color.

(No, I can't find a reference. Surprisingly the possibility to abbreviate long options isn't mentioned in the getopt_long documentation nor the GNU coding standards. I claim this is folklore.)

It's less useful now that common shells support completion for long options, but custom completion support for a command is not automatic, and support for custom completion in bash (the GNU shell) came about two decades after getopt_long was implemented (early 1980s to late 1990s IIRC).

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • 1
    This seems potentially dangerous and not future-proof. What if, at some time in the future and for whatever reason, we want to have ```ls --columns```? The sloppy variants may have seeped into many scripts, which will suddenly be broken. – Mårten W Nov 12 '21 at 23:48
  • @MårtenW it's the responsibility of the script writer to ensure that the abbreviation is unique, though, not the tool developers'. And since the only substring that can be guaranteed to remain unique is the full version, it's reasonable that only the full version is used in scripts expected to be future proof. – muru Nov 13 '21 at 00:38
  • [`man 3 getopts`](https://man7.org/linux/man-pages/man3/getopt.3.html) does mention the feature, but I'm not sure who authored it: "Long option names may be abbreviated if the abbreviation is unique or is an exact match for some defined option." – muru Nov 13 '21 at 00:40
  • @MårtenW In a script, you're supposed to use the full name of the option. This is old-fashioned design, from the time when reading the documentation was considered normal. – Gilles 'SO- stop being evil' Nov 13 '21 at 11:25
  • @muru: Thanks, I only looked into ```man getopt``` and ```man getopts```, not ```man 3 getopt``` (```man 3 getopts``` does not exist on my system). I now see that it is mentioned in both ```man getopt``` and ```man 3 getopt```. – Mårten W Nov 13 '21 at 13:47
1

I doubt there's anything else involved than the relevant function trying to be helpful. In interactive use, it might be beneficial for the utility to accept an abbreviation so the user can be lazy.

This is a question of Postel's law (i.e. "be lenient in what you accept, but strict in what you output"), and the leniency there is not always a good rule to follow, since behaviour that people get used to can influence future possibilities for change. In this case, a future option might make an earlier valid abbreviation invalid, but as long as script authors take the time to spell options out in full, there's not much risk of issues. Interactive users can use abbreviations more easily, since if they get an error after an upgrade, they can be assumed to be easily able to fix their command.

Scripts using an abbreviation could indeed be a problem, and avoiding the issues there would be the argument for not being lenient on input. But apparently in this case, the library authors have made the choice that accepting abbreviations is ok.

ilkkachu
  • 133,243
  • 15
  • 236
  • 397