命令行工具 flag
Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单。
# os.Args
如果仅仅是想获取命令行参数,可以使用 os.Args
来获取。
func main() {
if len(os.Args) > 0 {
for index, arg := range os.Args {
fmt.Printf("args[%d]=%v\n", index, arg)
}
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
go build -o hello
./hello a b c d 1
args[0]=./hello
args[1]=a
args[2]=b
args[3]=c
args[4]=d
args[5]=1
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
os.Args是一个存储命令行参数的字符串切片,它的第一个元素是执行文件的名称。
标准库 flag 的主要功能是实现命令行的解析,让我们在开发过程中能够非常方便的解析和处理命令行参数
# flag
flag 支持的参数类型有 bool、int、int64、uint、uint64、float、float64、string、duration。
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.Type()
格式:flag.Type(flag名, 默认值, 帮助信息)*Type
例如我们要定义姓名、年龄、婚否三个命令行参数,我们可以按如下方式定义:
name := flag.String("name", "张三", "姓名")
age := flag.Int("age", 18, "年龄")
married := flag.Bool("married", false, "婚否")
delay := flag.Duration("d", 0, "时间间隔")
1
2
3
4
2
3
4
需要注意的是,此时name、age、married、delay均为对应类型的指针。
# flag.TypeVar()
基本格式如下: flag.TypeVar(Type指针, flag名, 默认值, 帮助信息) 例如我们要定义姓名、年龄、婚否三个命令行参数,我们可以按如下方式定义:
var name string
var age int
var married bool
var delay time.Duration
flag.StringVar(&name, "name", "张三", "姓名")
flag.IntVar(&age, "age", 18, "年龄")
flag.BoolVar(&married, "married", false, "婚否")
flag.DurationVar(&delay, "d", 0, "时间间隔")
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# flag.Parse()
通过以上两种方法定义好命令行flag参数后,需要通过调用flag.Parse()
来对命令行参数进行解析。
支持的格式有三种
-flag // 仅支持布尔类型
-flag x // 仅支持非布尔类型
-flag=x // 都支持
1
2
3
2
3
-
和--
都可以使用,它们的作用是一样的。有些库使用-
表示短选项,--
表示长选项。
# flag 其他选项
flag.Args() ////返回命令行参数后的其他参数,以[]string类型
flag.NArg() //返回命令行参数后的其他参数个数
flag.NFlag() //返回使用的命令行参数个数
1
2
3
2
3
# 完整案例
func main() {
//定义命令行参数方式1
var name string
var age int
var married bool
var delay time.Duration
flag.StringVar(&name, "name", "张三", "姓名")
flag.IntVar(&age, "age", 18, "年龄")
flag.BoolVar(&married, "married", false, "婚否")
flag.DurationVar(&delay, "d", 0, "延迟的时间间隔")
//解析命令行参数
flag.Parse()
fmt.Println(name, age, married, delay)
//返回命令行参数后的其他参数
fmt.Println(flag.Args())
//返回命令行参数后的其他参数个数
fmt.Println(flag.NArg())
//返回使用的命令行参数个数
fmt.Println(flag.NFlag())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 使用
命令行参数使用提示:
$ ./flag_demo -help
Usage of ./flag_demo:
-age int
年龄 (default 18)
-d duration
时间间隔
-married
婚否
-name string
姓名 (default "张三")
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
正常使用命令行flag参数:
$ ./flag_demo -name zc --age 26 -married=false -d=1h30m
zc 26 false 1h30m0s
[]
0
4
1
2
3
4
5
2
3
4
5
# 参考
# 其他解析命令行参数库
flag 的局限性
对于复杂的命令行解析(如子命令、多级标志),flag
不太适合。
可以考虑使用第三方库,例如:
- Cobra (opens new window):流行的命令行工具框架,支持子命令。
- urfave/cli (opens new window):简洁的命令行解析库。
如果你正在实现一个复杂的命令行工具,flag
是一个好的起点,但复杂需求可能需要额外的工具支持。
上次更新: 2025/01/07, 14:41:11