【问题标题】:How to use the --name argument to getopt?如何使用 --name 参数来 getopt?
【发布时间】:2017-03-28 19:31:15
【问题描述】:

在以下示例中,我预计错误消息来自xyz,而不是来自getopt。我做错了什么?

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

我怎么让它说xyz: option requires an argument -- z;这不是--name 的用途吗?

更新

似乎是一个错误。我的getopt来自cygwin

$ getopt --version
getopt from util-linux 2.25.2

【问题讨论】:

    标签: command-line cygwin mingw getopt


    【解决方案1】:

    这似乎是某些版本的程序的错误。

    它适用于 Centos 7.3 和 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
    

    但它不在我的 MinGW shell 中(来自 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
    

    更新:它也适用于 Linux 的 2.27.1。而且它在(至少某些版本的)Cygwin 中不起作用。所以问题似乎出在 Windows 端口上(有趣的是,Mingw 和 Cygwin)。

    我会胡乱猜测(命中目标的可能性不大): getopt 程序,因为 this commit 试图处理一些具有/使用 getprogname/setprogname 来获取/设置“当前”程序名称的环境(特别是 BSD;不是 Linux) (而不是依赖argv[0])。

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

    现在,让我们想象一下

    1. Cygwin 和 MinGW/Msis 都支持这些功能。
    2. 但是,它们缺少 HAVE_SETPROGNAME 定义
    3. 此外,他们的getopt 函数(请注意,不是程序),就像BSD 版本一样,使用getprogname 而不是argv[0]

    在这种情况下,问题将得到解释。但是,我持怀疑态度——尤其是第 3 点。

    【讨论】:

    • 我有来自 cygwin 的 getopt from util-linux 2.25.2。是最近的错误还是与 Windows 相关?
    • 也许添加标签 cygwin 和 mingw 来吸引一些开发者......?
    • @rudimeier 我不认为 MinGW 定义了__linux__ 参见例如stackoverflow.com/a/647640/277304
    • 现在我可以在 Cygwin 上测试它了。您提到的提交确实修复了非 Linux 的行为,包括 Windows。但是你需要 util-linux >= 2.28 才能得到它。如果您无法更新,您可以使用 shell 技巧解决:bash -c 'exec -a "XYZ" getopt --name xyz --options "xyz:" -- -x -z'。请注意,固定的 getopt 版本将再次覆盖此技巧。
    【解决方案2】:

    这是一个错误(或只是一个不可移植性问题),已由commit 30fbf2f6util-linux 2.28 中修复。在此修复之前,它仅适用于 Linux、OSX 和一些 BSD 版本,但不适用于 WIN32 或 GNU-Hurd。

    如果您无法升级util-linux(可能难以在 Windows 上构建),那么您可以使用这个 shell 解决方法:

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

    请注意,如果有一天会更新 getopt,仍然使用 --name 选项将再次覆盖此技巧。

    当然,您也可以简单地将getopt 程序复制/链接/重命名为您想要的任何名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      • 2013-02-26
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多