getopt-like behavior in Go
How do I nicely parse a list of program parameters and automate handling "--开发者_运维百科help" and/or "--version" (such as "program [-d value] [--abc] [FILE1]
") in Go?
Google has created a getopt package (import "github.com/pborman/getopt"
) which provides the more standard command line parsing (vs the 'flag' package).
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!
Use the 'flag' package: http://golang.org/pkg/flag/. It doesn't do double-dash arguments, however. There isn't anything that exactly mimics GNU getopt behaviour (yet.)
From the section "Command Line UI", you have several libraries able to parse getopt-long parameters.
I tried, with a Go1.0.2:
- the code.google.com/p/opts-go (See its documentation), which isn't quite operational.
- the github.com/droundy/goopt (See its documentation), which has a complete set of examples.
Example:
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
}
Other default parameters provided with 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
go-flags is very complete, BSD licensed, and has a clear example.
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)
}
Another option is Kingping which provides support for all the standard goodies you have come to expect from a modern command line parsing library. It has --help
in multiple formats, sub-commands, requirements, types, defaults, etc. It's also still under development. It seems like the other suggestions here haven't been updated in a while.
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)
}
}
And the --help
output:
$ 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.
I made it just for you:
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])
}
}
}
see also https://play.golang.org/p/XtNXG-DhLI
Test:
$ ./8.out -help -version monkey business I need somebody Version Zero arg 3: monkey arg 4: business
I think what you want is docopt. I'll just refer you to an earlier answer I posted for the details.
As a simple library, you have since August 2017 github.com/rsc/getopt
To use, define flags as usual with package flag. Then introduce any aliases by calling
getopt.Alias
:
getopt.Alias("v", "verbose")
Or call
getopt.Aliases
to define a list of aliases:
getopt.Aliases(
"v", "verbose",
"x", "xylophone",
)
And:
In general Go flag parsing is preferred for new programs, because it is not as pedantic about the number of dashes used to invoke a flag (you can write
-verbose
or--verbose
, and the program does not care).This package is meant to be used in situations where, for legacy reasons, it is important to use exactly
getopt(3)
syntax, such as when rewriting in Go an existing tool that already usesgetopt(3)
.
One can simply use Golang own library "flag".
It has pretty much code to create CLI like application in GoLang. for Example :
srcDir := flag.String("srcDir", "", "Source directory of the input csv file.")
The above String method of flag library will expect one argument from command prompt.
Go to https://golang.org/pkg/flag/ for more reading.
Happy Learning...
精彩评论