1

In the following example, I expected the error message to come from xyz, not from getopt. What am I doing wrong?

/tmp> getopt  --name xyz --options "xyz:" -- -x
 -x --
/tmp> getopt  --name xyz --options "xyz:" -- -x -z
getopt: option requires an argument -- z
 -x --

How do I make it say xyz: option requires an argument -- z; isn't that what --name is for?

UPDATE

Seems to be a bug. My getopt comes from cygwin

$ getopt --version
getopt from util-linux 2.25.2
Miserable Variable
  • 28,432
  • 15
  • 72
  • 133

2 Answers2

1

It seems to be bug in some versions of the program.

It works for me in in Centos 7.3 and Fedora 19

[vps1 ~]$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
[vps1 ~]$ getopt  --name xyz --options "xyz:" -- -x -z
xyz: option requires an argument -- 'z'
 -x --
[vps1 ~]$  getopt -V
getopt from util-linux 2.23.2

But it doesn't in my MinGW shell (from Git for Windows)

$ getopt  --name xyz --options "xyz:" -- -x -z
getopt: option requires an argument -- z
-x --
$  getopt -V
getopt from util-linux 2.26.2

Update: It works also in 2.27.1 in Linux. And it doesn't work in (at least some version of) Cygwin. So the problem seems to be in the Windows ports (both Mingw and Cygwin, interestingly).

I'll throw a wild guess (not big probability of hitting the target): The getopt program, since this commit tries to deal with some environnments (in particular, BSD; not Linux) that have/use the getprogname/setprogname to get/set the "current" program name (instead of relying on argv[0]).

#if defined (HAVE_SETPROGNAME) && !defined (__linux__)
        setprogname(name);

Now, let's imagine that

  1. Cygwin and MinGW/Msis both support those functions.
  2. However, they lack the HAVE_SETPROGNAME define
  3. Further, their getopt functions (mind you, not the program), just like the BSD version, use getprogname instead of argv[0]

In that case, the problem would be explained. However, I'm skeptical - of point 3 especially.

leonbloy
  • 73,180
  • 20
  • 142
  • 190
  • I have `getopt from util-linux 2.25.2` from cygwin. Either a recent bug or windows related? – Miserable Variable Mar 28 '17 at 20:32
  • 1
    Perhaps adding the tags cygwin and mingw to attract some developers.... ? – leonbloy Mar 28 '17 at 21:13
  • @rudimeier I don't think that MinGW defines `__linux__` See eg http://stackoverflow.com/a/647640/277304 – leonbloy Mar 28 '17 at 23:02
  • Now I could test it on Cygwin. The commit you are mentioning really fixes the behavior for non-linux, including windows. But you need util-linux >= 2.28 to get it. In case you can't update you may workaround using shell tricks: `bash -c 'exec -a "XYZ" getopt --name xyz --options "xyz:" -- -x -z'`. Note that the fixed getopt version would override this trick again. – rudimeier Mar 29 '17 at 11:32
1

This is a bug (or just a non-portability issue) which is already fixed in util-linux 2.28, by commit 30fbf2f6. Before this fix it worked only on Linux, OSX and a few BSD flavors but not on WIN32 or GNU-Hurd for example.

If you can't upgrade util-linux (might be difficult to build on windows), then you could use this shell workaround:

bash -c 'exec -a "XYZ" getopt --options "xyz:" -- -x -z'

Note that still using the --name option would override this trick again once if getopt will be updated one day.

Of course you could also simply copy/link/rename the getopt program to whatever name you want.

rudimeier
  • 854
  • 1
  • 8
  • 20