30

I want to make my bash script deal with long parameters. I found getopt, but it isn't supported in OS X. Can anyone tell me why getopt was implemented by BSD, but not GNU? I tried building getopt in GNU C lib, but it failed for my poor skills with Linux.

Did anyone do this work?

apaderno
  • 28,547
  • 16
  • 75
  • 90
qiushuitian
  • 1,261
  • 4
  • 19
  • 31
  • possible duplicate of [Using getopts in bash shell script to get long and short command line options](http://stackoverflow.com/questions/402377/using-getopts-in-bash-shell-script-to-get-long-and-short-command-line-options) – ghoti Aug 28 '12 at 03:27

3 Answers3

33

There is a brew bottle for getopt.

Just run brew install gnu-getopt.

You can either specify the path for it like /usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt

Or use brew link --force gnu-getopt so it will be linked in /usr/local/bin/

Just be aware that forcing linking might be corrupting your system (as it replaces the system getopt by the gnu one).

See maybe later answer suggesting to define FLAGS_GETOPT_CMD (though few comments state issues with it).

Denis Rouzaud
  • 2,412
  • 2
  • 26
  • 45
  • 2
    If you want to use the `g`-prefix that `brew` uses for other GNU coreutils, you can add this to your `.bash_profile`: `if [[ -x /usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt ]] ; then alias ggetopt=/usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt; fi` – ijoseph Jun 02 '18 at 18:22
  • 2
    I can't link it, it dumps `echo 'export PATH="/usr/local/opt/gnu-getopt/bin:$PATH"' >> ~/.zshrc`. I ran the command and it still dump the same thing. Any advice? – Ennabah Dec 09 '18 at 17:01
  • I got the same message about using the echo command... after running it, you have to either restart your terminal or you should be able to run `source ~/.zshrc` – Nick DeMayo Jun 14 '19 at 11:40
  • Aliases cann't be used in script, so `cd /usr/local/bin/` and `ln -s $(brew --prefix)/opt/gnu-getopt/bin/getopt ggetopt`, then I can use it via `ggetopt` in both of command line and shell script. – Míng Oct 11 '22 at 07:57
22

I recommend using Homebrew to install gnu-getopt and then adding $FLAGS_GETOPT_CMD to your ~/.bash_profile file to specify the cmd path for getopt, pointing at the homebrew location, like so:

brew install gnu-getopt

Then follow directions from brew to add to your local path:

sudo echo 'export PATH="/usr/local/opt/gnu-getopt/bin:$PATH"' >> ~/.bash_profile

Then you can add FLAGS_GETOPT_CMD:

sudo echo 'export FLAGS_GETOPT_CMD="$(brew --prefix gnu-getopt)/bin/getopt"' >> ~/.bash_profile

Open a new terminal, or run . ~/.bash_profile in existing terminal to load changes

Run echo $FLAGS_GETOPT_CMD to confirm it was actually set in your console

sMyles
  • 2,418
  • 1
  • 30
  • 44
  • 2
    I love how people downvote but provide ZERO comments as to why ... tsk tsk – sMyles Feb 26 '18 at 21:18
  • this is just not working, maybe that's the reason of downvoting – denu Jan 17 '19 at 11:15
  • @denu probably bc of user error and not opening a new console or calling `. ~/.bash_profile` ... it works fine i just tested it on latest OSX ... and you can find numerous tutorials and comments online using it as well https://github.com/nvie/gitflow/issues/98 as example – sMyles Jan 17 '19 at 22:39
  • This doesn't work because it doesn't set the path. When you install gnu-getopt, brew tells you to do this: "If you need to have gnu-getopt first in your PATH run: echo 'export PATH="/usr/local/opt/gnu-getopt/bin:$PATH"' >> ~/.bash_profile" This works, because it sets it first in your path. – Steven Peterson Jan 18 '19 at 20:17
  • @StevenPeterson ah yeah i assumed users would follow brew instructions, added to post for clarification, thank you for pointing that out :) – sMyles Jan 19 '19 at 18:34
  • 1
    I don't understand what setting FLAGS_GETOPT_CMD does in practice? Who or what cares to look at the FLAGS_GETOPT_CMD environment variable when calling getopt? – Nathan Bell Oct 02 '19 at 21:20
  • 1
    @NathanBell it sets the brew based gnu-getopt to be used for getopt command – sMyles Jul 01 '20 at 15:33
  • This did not work for me. @sMyles. I've created a post about it [here](https://stackoverflow.com/questions/76519264/how-can-i-get-gnu-getopt-correctly-installed-on-macos) – user129393192 Jun 21 '23 at 01:11
2

It's generally a better idea to use getopts instead, and stick with short options. You can see getopts in action in this StackOverflow Q&A. Short options are more standard throughout OSX command line tools, and consistency is a good thing.

Also, getopts is built in to bash, so it's definitely available in OSX, as well as every other platform that can run bash.

Note that there is a getopt is also available in OSX. From Terminal, type man getopt to see its documentation. It doesn't support long options. This is a good reason not to use long options when you're writing tools to run on OSX.

If you want to do this anyway, you can install getopt from macports. Alternately, if you want better portability, you can roll your own long argument handling.

Post some code, and we'll help debug it.

Community
  • 1
  • 1
ghoti
  • 45,319
  • 8
  • 65
  • 104
  • 4
    Short options tend to be unreadable, especially if there are lot of them. Perfectly reasonable to want to use them. – Christopher Barber Aug 14 '18 at 00:37
  • 2
    What is "a good reason not to use long options when you're writing tools" ? – jalanb Mar 16 '20 at 01:45
  • 1
    @jalanb, lack of support for long options in OSX would seem to be a good reason not to use long options when writing shell tools for OSX. – ghoti Mar 16 '20 at 04:08
  • Maybe is good reason not to use a Macintosh. Seems more reasonable to expect Mac users to get GNU getopt than to assume rest of GNU-based world do without long args. – pauljohn32 Jun 21 '23 at 21:27