10

The Linux foundation list of standard utilities includes getopts but not getopt. Similar for the Open Group list of Posix utilities.

Meanwhile, Wikipedia's list of standard Unix Commands includes getopt but not getopts. Similarly, the Windows Subsystem for Linux (based on Ubuntu based on Debian) also includes getopt but not getopts (and it is the GNU Enhanced version).

balter@spectre:~$ which getopt
/usr/bin/getopt
balter@spectre:~$ getopt -V
getopt from util-linux 2.27.1
balter@spectre:~$ which getopts
balter@spectre:~$ 

So if I want to pick one that I can be the most confident that anyone using one of the more standard Linux distros (e.g. Debian, Red Hat, Ubuntu, Fedora, CentOS, etc.), which should I pick?

Note:

thanks to Michael and Muru for explaining about builtin vs executable. I had just stumbled across this as well which lists bash builtins.

abalter
  • 261
  • 5
    getopts is a shell built-in (as both of your sources identify), not an executable. It's in every POSIX shell, including the one from WSL Ubuntu. What are you actually trying to do with it? It's not impossible that there are cases where it matters which you use, but there's not enough information here to say. – Michael Homer May 14 '18 at 04:54
  • Wanting to use either getopt or getopts at all is a warning sign that your shell script is probably complicated enough that you should consider rewriting it in a better programming language, e.g. Perl, Python, Ruby, even PHP. – zwol May 14 '18 at 15:44
  • 2
    @zwol -- I could throw it back at you and say your statement indicates you aren't a skilled bash programmer ;) I work in a field where we pipeline other command line programs, and run the pipelines on a cluster. Using a bash script for this is by far the most efficient method. I've had great success with using getopts in this application. I use Python when it is the better tool. – abalter May 14 '18 at 16:38

2 Answers2

17

which is the wrong tool. getopts is usually also a builtin:

Since getopts affects the current shell execution environment, it is generally provided as a shell regular built-in.

~ for sh in dash ksh bash zsh; do "$sh" -c 'printf "%s in %s\n" "$(type getopts)" "$0"'; done
getopts is a shell builtin in dash
getopts is a shell builtin in ksh
getopts is a shell builtin in bash
getopts is a shell builtin in zsh

If you're using a shell script, you can safely depend on getopts. There might be other reasons to favour one or the other, but getopts is standard.

See also: Why not use "which"? What to use then?

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
muru
  • 72,889
  • 2
    getopt was dropped a while ago in favor of getopts. However, the new GNU-enhanced getopt seems to have improved over getopts. But if getopts is the Posix standard, then I should stick to that for the time being. – abalter May 14 '18 at 05:37
5

I too would prefer getopts over getopt for the following reasons:

getopt Cons

  1. External utility
  2. Cannot handle empty argument string or arguments with embedded whitespace in traditional version

getopts Pros

  1. Works in any POSIX shell and is portable
  2. Works well with -a -b as well as -ab
Arushix
  • 1,290
  • Very clear. Thanks! Especially the information about -a -b === -ab – abalter May 17 '18 at 15:06
  • I wish that you can elobrate more about getopt that cannot handle empty argument (on which platform)?. Did you test it? It does handle that well on my ubuntu and debian OS. – Kalib Zen Dec 24 '22 at 08:24