16

如何很好地解析程序参数列表并program [-d value] [--abc] [FILE1]在 Go 中自动处理“--help”和/或“--version”(例如“”)?

4

9 回答 9

22

Google 已经创建了一个getopt包 ( import "github.com/pborman/getopt"),它提供了更标准的命令行解析(相对于 'flag' 包)。

package main

import (
    "fmt"
    "os"
    "github.com/pborman/getopt"
)

func main() {
    optName := getopt.StringLong("name", 'n', "", "Your name")
    optHelp := getopt.BoolLong("help", 0, "Help")
    getopt.Parse()

    if *optHelp {
        getopt.Usage()
        os.Exit(0)
    }

    fmt.Println("Hello " + *optName + "!")
}

 

$ ./hello --help
Usage: hello [--help] [-n value] [parameters ...]
     --help        Help
 -n, --name=value  Your name

$ ./hello --name Bob
Hello Bob!
于 2014-09-30T22:30:19.857 回答
15

使用“标志”包: http: //golang.org/pkg/flag/。但是,它不执行双破折号参数。没有任何东西可以完全模仿 GNU getopt 行为(还没有。)

于 2009-11-11T11:07:12.367 回答
10

在“命令行 UI”部分,您有几个能够解析getopt-long 参数的库。

我用 Go1.0.2 试过:

例子:

package main

import (
    "fmt"
    goopt "github.com/droundy/goopt"
)

func main() {
    fmt.Println("flag")
    goopt.NoArg([]string{"--abc"}, "abc param, no value", noabc)

    goopt.Description = func() string {
        return "Example program for using the goopt flag library."
    }
    goopt.Version = "1.0"
    goopt.Summary = "goopt demonstration program"
    goopt.Parse(nil)
}

func noabc() error {
    fmt.Println("You should have an --abc parameter")
    return nil
}

提供的其他默认参数goopt

 --help               Display the generated help message (calls Help())
 --create-manpage     Display a manpage generated by the goopt library (uses Author, Suite, etc)
 --list-options       List all known flags
于 2012-07-23T11:04:00.533 回答
7

go-flags非常完整,BSD 许可,并且有一个清晰的例子

var opts struct {
      DSomething string `short:"d" description:"Whatever this is" required:"true"`
      ABC bool `long:"abc" description:"Something"`
}

fileArgs, err := flags.Parse(&opts)

if err != nil {
    os.Exit(1)
}
于 2013-03-09T16:48:23.447 回答
5

另一个选项是Kingping,它为您期望从现代命令行解析库中获得的所有标准好东西提供支持。它有--help多种格式、子命令、要求、类型、默认值等。它还在开发中。这里的其他建议似乎有一段时间没有更新了。

package main

import (
  "os"
  "strings"
  "gopkg.in/alecthomas/kingpin.v2"
)

var (
  app      = kingpin.New("chat", "A command-line chat application.")
  debug    = app.Flag("debug", "Enable debug mode.").Bool()
  serverIP = app.Flag("server", "Server address.").Default("127.0.0.1").IP()

  register     = app.Command("register", "Register a new user.")
  registerNick = register.Arg("nick", "Nickname for user.").Required().String()
  registerName = register.Arg("name", "Name of user.").Required().String()

  post        = app.Command("post", "Post a message to a channel.")
  postImage   = post.Flag("image", "Image to post.").File()
  postChannel = post.Arg("channel", "Channel to post to.").Required().String()
  postText    = post.Arg("text", "Text to post.").Strings()
)

func main() {
  switch kingpin.MustParse(app.Parse(os.Args[1:])) {
  // Register user
  case register.FullCommand():
    println(*registerNick)

  // Post message
  case post.FullCommand():
    if *postImage != nil {
    }
    text := strings.Join(*postText, " ")
    println("Post:", text)
  }
}

--help输出:

$ chat --help
usage: chat [<flags>] <command> [<flags>] [<args> ...]

A command-line chat application.

Flags:
  --help              Show help.
  --debug             Enable debug mode.
  --server=127.0.0.1  Server address.

Commands:
  help [<command>]
    Show help for a command.

  register <nick> <name>
    Register a new user.

  post [<flags>] <channel> [<text>]
    Post a message to a channel.
于 2016-03-16T01:14:29.533 回答
4

我只是为你做的:

package main

import (
  "fmt";
  "os"
)

func main() {
  for i, arg := range os.Args {
    if arg == "-help" {
      fmt.Printf ("I need somebody\n")
    }else if arg == "-version" {
      fmt.Printf ("Version Zero\n")
    } else {
      fmt.Printf("arg %d: %s\n", i, os.Args[i])
    }
  }
}

另见https://play.golang.org/p/XtNXG-DhLI

测试:

$ ./8.out -help -version 猴子业务
我需要一个人
零版本
参数 3:猴子
参数 4:商业
于 2009-11-11T13:17:25.303 回答
2

我认为你想要的是docopt。我只是将您推荐给我发布的早期答案以获取详细信息。

于 2013-11-20T02:42:34.583 回答
2

作为一个简单的库,您从 2017 年 8 月开始github.com/rsc/getopt

要使用,请像往常一样使用包标志定义标志。然后通过调用引入任何别名getopt.Alias

getopt.Alias("v", "verbose")

或调用getopt.Aliases定义别名列表:

getopt.Aliases(
    "v", "verbose",
    "x", "xylophone",
)

和:

一般来说,Go 标志解析对于新程序来说是首选,因为它并不像用于调用标志的破折号数量那样迂腐(你可以写-verboseor --verbose,程序并不关心)。

此包旨在用于由于遗留原因,准确使用getopt(3)语法很重要的情况,例如在 Go 中重写已经使用的现有工具时getopt(3)

于 2019-04-18T16:19:21.520 回答
0

可以简单地使用 Golang 自己的库“标志”。

它有很多代码可以在 GoLang 中创建类似 CLI 的应用程序。例如 :

srcDir := flag.String("srcDir", "", "Source directory of the input csv file.")

上述标志库的 String 方法将期望来自命令提示符的一个参数。

更多阅读请访问https://golang.org/pkg/flag/

快乐学习...

于 2020-01-14T06:11:10.323 回答