【发布时间】:2010-12-15 09:56:51
【问题描述】:
如何很好地解析程序参数列表并在 Go 中自动处理“--help”和/或“--version”(例如“program [-d value] [--abc] [FILE1]”)?
【问题讨论】:
-
2019:
github.com/rsc/getopt似乎是一个简单的选择:见my answer below
标签: go
如何很好地解析程序参数列表并在 Go 中自动处理“--help”和/或“--version”(例如“program [-d value] [--abc] [FILE1]”)?
【问题讨论】:
github.com/rsc/getopt 似乎是一个简单的选择:见my answer below
标签: go
Google 已经创建了一个 getopt 包 (import "github.com/pborman/getopt"),它提供了更标准的命令行解析(与“标志”包相比)。
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!
【讨论】:
使用“标志”包:http://golang.org/pkg/flag/。但是,它不执行双破折号参数。还没有任何东西可以完全模仿 GNU getopt 行为。
【讨论】:
在“命令行 UI”部分,您有几个库能够解析 getopt-long parameters。
我用 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
【讨论】:
【讨论】:
另一个选项是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.
【讨论】:
我只是为你做的:
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:商业【讨论】:
-d value)或默认值;如果程序员自己动手,他们不太可能满足用户的期望(比如--key value 和--key=value 的等价性)。手工滚动 --help 使得生成制表符补全变得困难,并且需要手动维护空间上不同的代码。实际代码可能应该一方面将 Args 划分为标志及其值,另一方面将非标志 args 划分为。当一个新手就参数解析等棘手但基本的事情寻求指导时,正确的答案不是“自己动手”。
我认为你想要的是 docopt。我会推荐你to an earlier answer我发布的详细信息。
【讨论】:
作为一个简单的库,您从 2017 年 8 月开始拥有 github.com/rsc/getopt
要使用,请像往常一样使用包标志定义标志。然后通过调用
getopt.Alias引入任何别名:
getopt.Alias("v", "verbose")
或调用
getopt.Aliases定义别名列表:
getopt.Aliases(
"v", "verbose",
"x", "xylophone",
)
还有:
一般来说,Go 标志解析对于新程序来说是首选,因为它对用于调用标志的破折号数量没有那么迂腐(你可以写
-verbose或--verbose,程序并不关心)。此包旨在用于由于遗留原因,准确使用
getopt(3)语法很重要的情况,例如在 Go 中重写已经使用 @987654331 的现有工具时@。
【讨论】:
可以简单地使用 Golang 自己的库“flag”。
它有很多代码可以在 GoLang 中创建类似 CLI 的应用程序。例如:
srcDir := flag.String("srcDir", "", "Source directory of the input csv file.")
上述标志库的 String 方法需要一个来自命令提示符的参数。
转至https://golang.org/pkg/flag/ 了解更多信息。
快乐学习...
【讨论】: