Go之flag
定义flag参数,有三种方式 1. 通过flag.String(), Bool(), Int() 等flag.Xxx()方法,该种方式返回一个相应的指针 var ip = flag.Int("flagname", 1234, "help message for flagname") 2.通过flag.XxxVar()方法将flag绑定到一个变量,该种方式返回值类型 var flagvar int flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") 3. 通过flag.Var()绑定自定义类型,自定义类型需要实现Value接口(Receives必须为指针),默认值为该变量类型的初始值 flag.Var(&flagVal, "name", "help message for flagname")
测试代码
package main import ( "flag" "os" "fmt" ) func main() { fmt.Printf("os.Args[]:%s\n", os.Args); fmt.Println("tail: ", flag.Args()) //定义标志 //1.name:命令行参数名称,比如 -b, -help //2.value:默认值,未显式指定的参数,给出隐式的默认值 //3.usage:提示信息,如果给出的参数不正确或者需要查看帮助 -help,那么会给出这里指定的字符串 // 这声明了一个string flag,都存储在指针dir中,类型为 *string。 dir := flag.String("b", "~/soft", "backup path") mode := flag.Bool("d", false, "debug mode") //使用 Var() 函数将标志绑定到一个变量。 var flagInt int flag.IntVar(&flagInt, "i", 123, "this is a integer") //解析命令行标志,必须在定义了所有标志之后并且在程序访问标志之前调用。 flag.Parse() //NFlag 返回已设置的命令行标志的数量。 fmt.Println(flag.NFlag()) //NArg 是标志处理后剩余的参数数量。 fmt.Println(flag.NArg()) fmt.Println("dir: ", *dir) fmt.Println("mode: ", *mode) fmt.Println("flagInt: ", flagInt) fmt.Println("tail: ", flag.Args())//剩余未处理的参数 }
结果
cts@cts-pc:~/test/bak$ go run first.go --help os.Args[]:[/tmp/go-build331859944/b001/exe/first --help] tail: [] Usage of /tmp/go-build331859944/b001/exe/first: -b string backup path (default "~/soft") -d debug mode -i int this is a integer (default 123) cts@cts-pc:~/test/bak$ cts@cts-pc:~/test/bak$ cts@cts-pc:~/test/bak$ go run first.go -b ssxx -d=true -i 32 1111 2222 os.Args[]:[/tmp/go-build216792631/b001/exe/first -b ssxx -d=true -i 32 1111 2222] tail: [] 3 2 dir: ssxx mode: true flagInt: 32 tail: [1111 2222]
测试2
package main import ( "os" "flag" "fmt" ) func main() { flagSet := flag.NewFlagSet("main", flag.ExitOnError) // 参数定义 //version = flagSet.Bool("version", false, "print version string") flagSet.Bool("version", false, "print version string") // 解析 flagSet.Parse(os.Args[1:]) // 使用参数 (如果参数没有赋值) v := flagSet.Lookup("version").Value.(flag.Getter).Get().(bool) fmt.Println(v) }
cts@cts-pc:~/test$ go run t.go -version=true
true
cts@cts-pc:~/test$ go run t.go --help
Usage of main:
-version
print version string
测试3
package main import ( "flag" "fmt" "os" ) func main(){ foostr := flag.NewFlagSet("str",flag.ExitOnError) strValue := foostr.String("a","string","打印字符串") intValue := foostr.Int("b",1,"打印数值") if len(os.Args)<1{ fmt.Println("expected 'str' subcommands") os.Exit(1) } switch os.Args[1]{ case "str": foostr.Parse(os.Args[2:]) fmt.Println("a", *strValue) fmt.Println("b", *intValue) default: fmt.Println("expected 'str' subcommands") os.Exit(1) } }
cts@cts-pc:~/test$ go run s.go str a string b 1 cts@cts-pc:~/test$ go run s.go str -a sssss -b 123 a sssss b 123 cts@cts-pc:~/test$ go run s.go --help expected 'str' subcommands exit status 1
测试四
import ( "flag" "fmt" "os" ) func main() { var value string flag.StringVar(&value, "v", "defaultValue", "Usage:xxx") flag.Parse() fmt.Println("Args1:", flag.Arg(0)) fmt.Println("Args2:", flag.Arg(1)) fmt.Println("Args3:", flag.Arg(2)) fmt.Println("value:", value) fmt.Println("os.Args[0]:", os.Args[0]) fmt.Println("os.Args[1]:", os.Args[1]) fmt.Println("os.Args[2]:", os.Args[2]) }
os.Args[0]: ./test os.Args[1]: -v os.Args[2]: sss cts@cts-pc:~/test$ cts@cts-pc:~/test$ cts@cts-pc:~/test$ ./test 111 222 333 -v sss Args1: 111 Args2: 222 Args3: 333 value: defaultValue os.Args[0]: ./test os.Args[1]: 111 os.Args[2]: 222
-v放在后面,为什么没有被正确解析出来?这是因为解析到非FLag变量就停止解析Flag参数了。所以,flag参数应该放在普通参数的前面指定。
// These examples demonstrate more intricate uses of the flag package. package main import ( "errors" "flag" "fmt" "strings" "time" ) // Example 1: A single string flag called "species" with default value "gopher". var species = flag.String("species", "gopher", "the species we are studying") // Example 2: Two flags sharing a variable, so we can have a shorthand. // The order of initialization is undefined, so make sure both use the // same default value. They must be set up with an init function. var gopherType string func init() { const ( defaultGopher = "pocket" usage = "the variety of gopher" ) flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage) flag.StringVar(&gopherType, "g", defaultGopher, usage+" (shorthand)") } // Example 3: A user-defined flag type, a slice of durations. type interval []time.Duration // String is the method to format the flag's value, part of the flag.Value interface. // The String method's output will be used in diagnostics. func (i *interval) String() string { return fmt.Sprint(*i) } // Set is the method to set the flag value, part of the flag.Value interface. // Set's argument is a string to be parsed to set the flag. // It's a comma-separated list, so we split it. func (i *interval) Set(value string) error { // If we wanted to allow the flag to be set multiple times, // accumulating values, we would delete this if statement. // That would permit usages such as // -deltaT 10s -deltaT 15s // and other combinations. if len(*i) > 0 { return errors.New("interval flag already set") } for _, dt := range strings.Split(value, ",") { duration, err := time.ParseDuration(dt) if err != nil { return err } *i = append(*i, duration) } return nil } // Define a flag to accumulate durations. Because it has a special type, // we need to use the Var function and therefore create the flag during // init. var intervalFlag interval func init() { // Tie the command-line flag to the intervalFlag variable and // set a usage message. flag.Var(&intervalFlag, "deltaT", "comma-separated list of intervals to use between events") } func main() { // All the interesting pieces are with the variables declared above, but // to enable the flag package to see the flags defined there, one must // execute, typically at the start of main (not init!): flag.Parse() // We don't run it here because this is not a main function and // the testing suite has already parsed the flags. fmt.Printf("species:%s\n", *species) fmt.Printf("gopherType:%s\n", gopherType) fmt.Println(intervalFlag) }
cts@cts-pc:~/test/bak$ ./bak --help Usage of ./bak: -deltaT value comma-separated list of intervals to use between events -g string the variety of gopher (shorthand) (default "pocket") -gopher_type string the variety of gopher (default "pocket") -species string the species we are studying (default "gopher") cts@cts-pc:~/test/bak$ cts@cts-pc:~/test/bak$ cts@cts-pc:~/test/bak$ ./bak -g "gggg" -species "ssssss" -deltaT 61m,72h,80s species:ssssss gopherType:gggg [1h1m0s 72h0m0s 1m20s]