英文:
How can I have more than only two command-line flags controlling the same behavior?
问题
在Go语言中,我知道如何使用github.com/pborman/getopt
包来执行类似于getopt
的命令行解析。
然而,这个包似乎只能支持每个命令行选项的一个字符串版本和一个rune版本。有时候我想要的不仅仅是两种指定选项的方式。例如,对于一个名为prog
的假设程序,我希望以下所有方式都执行完全相同的功能:
prog -r [其他参数]
prog -R [其他参数]
prog --recurse [其他参数]
prog --recursive [其他参数]
我知道我可以像下面这样做,只需测试每个变量optRecurse
和optRecursive
的值...
optRecurse := getopt.BoolLong("recurse", 'r', "run recursively")
optRecursive := getopt.BoolLong("recursive", 'R', "run recursively")
然而,理想情况下,我希望能够通过一次调用来获得这四种可能性中的一个值。
我希望有一种类似于Ruby的OptionParser
包的方式,可以处理任何给定命令行选项的两种以上可能性。下面是一个Ruby的例子...
$isRecursive = false
parser = OptionParser.new {
|opts|
opts.on('-r', '-R', '--recurse', '--recursive') {
|arg|
# 所有四种可能性都在一个单独的"opts.on"块中处理。
$isRecursive = true
}
# ... 其他代码 ...
}
我对Go语言相对较新,我可能在寻找答案时忽略了一些东西。
英文:
In Go, I know how to use the github.com/pborman/getopt
package to perform getopt
-like command-line parsing.
However, this package only seems to be able to support one string version and one rune version of each command-line option. Sometimes I want more than simply two ways to specify an option. For example, for a hypothetical program called prog
, I'd like the following to all perform the exact, same function:
prog -r [other args]
prog -R [other args]
prog --recurse [other args]
prog --recursive [other args]
I know that I can do something like the following and just test for the value of each of the variables optRecurse
and optRecursive
...
optRecurse := getopt.BoolLong("recurse", 'r', "run recursively")
optRecursive := getopt.BoolLong("recursive", 'R', "run recursively")
However, ideally, I'd like to make one, single call that will give me one value for any of these four possibilities.
I want something that works similarly to Ruby's OptionParser
package with regard to more than two possibilities for any given command-line option. Here's a Ruby example ...
$isRecursive = false
parser = OptionParser.new {
|opts|
opts.on('-r', '-R', '--recurse', '--recursive') {
|arg|
# All four possibilities are handled with one, single "opts.on" block.
$isRecursive = true
}
# ... etc. ...
}
I'm relatively new to Go, and I may very well have overlooked something in my searches for an answer to this question.
答案1
得分: 1
在我看来,提供超过两种方式来指定任何给定的命令行选项并不“奇怪”。
我最初在这个“回答”中提到的github.com/clagraff/argparse
包已经不再受支持。然而,我找到了一个更现代且仍受支持的包,可以使用它以类似于其他语言(如Ruby和Python)的参数解析包所提供的方式来实现这种功能:github.com/tcler/cmdline-go/cmdline
。
以下是一个示例程序,演示了如何在Go中实现这一点...
package main
import (
"fmt";
"os";
"github.com/tcler/cmdline-go/cmdline";
)
func main() {
var nargv []string = os.Args[1:]
var cli cmdline.Cmdline
var options = []cmdline.Option {
{Help: "Options:"},
{Names: "r R recurse recursive", Argtype: cmdline.N, Help: "Run recursively"},
}
cli = cmdline.Parse(options, nargv)
has_invalid := false
for _, v := range cli.InvalidOptions {
if !has_invalid {
fmt.Println()
}
fmt.Println(v)
has_invalid = true
}
if has_invalid {
fmt.Println()
cmdline.GetUsage(options)
os.Exit(1)
}
recursivemode := cli.GetOptionArgString("r")
fmt.Printf("recursive mode: \"%s\"\n", recursivemode)
}
我可以以以下四种方式运行该程序,它在每种情况下的行为都相同...
% go run prog.go -r
% go run prog.go -R
% go run prog.go --recurse
% go run prog.go --recursive
在这四种情况下,它总是输出以下内容:
recursive mode: "set"
如果我不带任何选项运行(即仅运行go run prog.go
),它会输出:
recursive mode: ""
如果我带有任何其他命令行参数运行,例如-x
,它会失败并显示以下内容:
% go run prog.go -x
option: 'x' undefined
Options:
-r -R --recurse --recursive
Run recursively
[加上一些其他的“帮助”文本]
因此,现在我可以编写允许使用多于两种方式来指定任何命令行选项的Go程序。
<details>
<summary>英文:</summary>
In my opinion, there is nothing "odd" about offering more than two ways to specify any given command-line option.
The `github.com/clagraff/argparse` package that I originally mentioned here in this "Answer" is no longer being supported. However, I found a more modern and still supported package that I can use which offers that exact capability in a manner which is similar to what's offered in argument-parsing packages for other languages such as Ruby and Python: `github.com/tcler/cmdline-go/cmdline`.
Here is a sample program which illustrates how this can work in Go ...
package main
import (
"fmt";
"os";
"github.com/tcler/cmdline-go/cmdline";
)
func main() {
var nargv []string = os.Args[1:]
var cli cmdline.Cmdline
var options = []cmdline.Option {
{Help: "Options:"},
{Names: "r R recurse recursive", Argtype: cmdline.N, Help: "Run recursively"},
}
cli = cmdline.Parse(options, nargv)
has_invalid := false
for _, v := range cli.InvalidOptions {
if !has_invalid {
fmt.Println()
}
fmt.Println(v)
has_invalid = true
}
if has_invalid {
fmt.Println()
cmdline.GetUsage(options)
os.Exit(1)
}
recursivemode := cli.GetOptionArgString("r")
fmt.Printf("recursive mode: \"%s\"\n", recursivemode)
}
I can run the program in all four of the following ways, and it behaves the same in each case ...
% go run prog.go -r
% go run prog.go -R
% go run prog.go --recurse
% go run prog.go --recursive
In all four of these these cases, it always outputs the following:
recursive mode: "set"
If I run without any option (*i.e.*, simply `go run prog.go`), it outputs this:
recursive mode: ""
And if I run with any other command-line argument, such as `-x` for example, it fails as follows:
% go run prog.go -x
option: 'x' undefined
Options:
-r -R --recurse --recursive
Run recursively
[ plus some other "help" text ]
So, now I can write Go programs which allow more than two ways to specify any command-line option.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论