在写命令行程序(工具、server)时,对命令参数进行解析是常见的需求。各种语言一般都会提供解析命令行参数的方法或库,以方便程序员使用。如果命令行参数纯粹自己写代码来解析,对于比较复杂的,还是挺费劲的。在 go 标准库中提供了一个包:flag,方便进行命令行解析。

使用示例

我们以 docker 为例,当我们输入 docker --help,输出信息如下:

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Options:
      --config string      Location of client config files (default "/root/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with
                           "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/root/.docker/ca.pem")

... ... 下文略去 ... ...

所以说,flag 包实现了命令行参数的解析的一个标准库,当然还有其他标准库也能实现类似的功能,例如:os.Args,但是使用 flag 处理会更加方便。

flag基本使用

参数类型:

flag包支持的命令行参数类型有 boolintint64uintuint64floatfloat64stringduration

flag参数 有效值
字符串flag 合法字符串
整数flag 1234、0664、0x1234等类型,也可以是负数。
浮点数flag 合法浮点数
bool类flag 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False。
时间段flag 任何合法的时间段字符串。如”300ms”、”-1.5h”、”2h45m”。 合法的单位有”ns”、”us” 、“µs”、”ms”、”s”、”m”、”h”。

定义命令行flag参数:

有以下两种常用的定义命令行flag参数的方法。

flag.Type()

格式

flag.Type("flag名", "默认值", "帮助信息")
flag.Parse() // 解析命令行参数写入注册的flag里

测试

func main() {
	name := flag.String("name", "default_name", "Help:Please input your name")
	age := flag.Int("age", 0, "Help:Please input your age")
	flag.Parse()

	fmt.Println(*name)
	fmt.Println(*age)
}

flag.TypeVar()

格式

flag.IntVar(&flagvar, "flagname", "默认值", "帮助信息")
flag.Parse() // 解析命令行参数写入注册的flag里

测试

func main() {
	var name string
	var age int

	flag.StringVar(&name,"name", "default_name", "Help:Please input your name")
	flag.IntVar(&age,"age", 0, "Help:Please input your age")
	flag.Parse()

	fmt.Println(name)
	fmt.Println(age)
}

命令行参数指定方法

-flag
-flag=xxx
-flag xxx  // 只有非bool类型的flag可以
--flag xxx // 只有非bool类型的flag可以
--flag=xxx

其中,布尔类型的参数必须使用等号的方式指定。
Flag解析在第一个非flag参数(单个”-“不是flag参数)之前停止,或者在终止符”–“之后停止。

flag其他函数

flag.Args()  ////返回命令行参数后的其他参数,以[]string类型
flag.NArg()  //返回命令行参数后的其他参数个数
flag.NFlag() //返回使用的命令行参数个数