Go语言flag包基本使用

Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单。

os.Args使用

如果你只是简单的想要获取命令行参数,可以像下面的代码示例一样使用os.Args来获取命令行参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
"fmt"
"os"
)

func main() {
//os.Args是一个[]string
fmt.Println("osArgs:", os.Args) // [./args_demo a b c d]
if len(os.Args) > 0{
for index,v:=range os.Args{
fmt.Println(index,v)
}
}
}

将上面的代码执行go build -o "args_demo"编译之后,执行:

1
2
3
4
5
6
$ ./args_demo a b c d
0 ./args_demo
1 a
2 b
3 c
4 d

os.Args是一个存储命令行参数的字符串切片,它的第一个元素是执行文件的名称。

flag包基本使用

本文介绍了flag包的常用函数和基本用法,更详细的内容请查看官方文档

导入flag包

1
import flag

flag参数类型

flag包支持的命令行参数类型有boolintint64uintuint64float``float64stringduration

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名, 默认值, 帮助信息)*Type 例如我们要定义主机ip、端口号、帮助信息三个命令行参数,我们可以按如下方式定义:

1
2
3
4
host := flag.String("H","127.0.0.1","主机地址")
port := flag.Int("P",22,"端口号")
h := flag.Bool("h",false,"帮助信息")
help := flag.Bool("help",false,"帮助信息")

需要注意的是,此时host port h help均为对应类型的指针,当程序访问值的时候需要在变量名前加上*才可以访问,例如:*host *port

flag.TypeVar()

基本格式如下: flag.TypeVar(Type指针, flag名, 默认值, 帮助信息) 例如我们要定义主机ip、端口号、帮助信息三个命令行参数,我们可以按如下方式定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 命令行中传递的参数进行解析,将指定命令参数解析成变量
func main() {
var (
host string
port int
h bool
help bool
)
flag.StringVar(&host, "H", "127.0.0.1", "连接地址234")
flag.IntVar(&port, "P", 22, "端口号")
flag.BoolVar(&h,"h",false,"帮助信息")
flag.BoolVar(&help,"help",false,"帮助信息")
}

flag.Parse()

通过以上两种方法定义好命令行flag参数后,需要通过调用flag.Parse()来对命令行参数进行解析。

支持的命令行参数格式有以下几种:

  • -flag xxx (使用空格,一个-符号)
  • --flag xxx (使用空格,两个-符号)
  • -flag=xxx (使用等号,一个-符号)
  • --flag=xxx (使用等号,两个-符号)

其中,布尔类型的参数必须使用等号的方式指定。

Flag解析在第一个非flag参数(单个”-“不是flag参数)之前停止,或者在终止符”–“之后停止。

flag其他函数

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

完整示例

定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package main

import (
"flag"
"fmt"
)

// 命令行中传递的参数进行解析,将指定命令参数解析成变量
func main() {
var (
host string
port int
h bool
help bool
)

// 将传递的不同命令行参数传递到不同的变量上
flag.StringVar(&host, "H", "127.0.0.1", "连接地址234")
flag.IntVar(&port, "P", 22, "端口号")
flag.BoolVar(&h, "h", false, "帮助信息")
flag.BoolVar(&help, "help", false, "帮助信息")

// 定义帮助信息页
flag.Usage = func() {
fmt.Println("usage: testflag [-H 127.0.0.1] [-P 22] -h && --help获取帮助信息")
flag.PrintDefaults()
}

// 解析传递的命令行参数列表
flag.Parse()
fmt.Println(host, port, h, help)

// 返回命令行参数后的其他参数(未定义的参数被传递进来)
fmt.Println(flag.Args())
// 返回命令行参数后的其他参数个数
fmt.Println(flag.NArg())
// 返回使用的命令行参数个数
fmt.Println(flag.NFlag())

// 判断是否打印帮助文档
if h || help {
flag.Usage()
return
}
}

使用

命令行参数使用提示:

1
2
3
4
5
6
7
8
9
$ ./args_demo -h
usage: testflag [-H 127.0.0.1] [-P 22] -h && --help获取帮助信息
-H string
连接地址234 (default "127.0.0.1")
-P int
端口号 (default 22)
-h 帮助信息
-help
帮助信息

正常使用命令行flag参数:

1
2
$ ./args_demo -H 127.0.0.2 -P 23   
127.0.0.2 23 false false

使用非flag命令行参数:

1
2
3
$ ./args_demo 1 2 3 
127.0.0.1 22 false false
[1 2 3]