0

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

3
  • 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, 2021 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, 2021 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, 2021 at 13:49

2 Answers 2

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).

5
  • 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, 2021 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, 2021 at 0:38
  • man 3 getopts 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, 2021 at 0: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. Nov 13, 2021 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, 2021 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.