命令行参数工具 goflags

编写工具的时候经常会利用到命令行参数解析,发现了一款非常好用的命令行工具解析包 goflags。

查看官方文档了解更多细节。

1
2
https://github.com/projectdiscovery/goflags
https://pkg.go.dev/github.com/projectdiscovery/goflags

获取包。

1
go get "github.com/projectdiscovery/goflags"

引入之后可以新建一个 FlagSet,而且可以设置一个命令描述,可以在使用 -h 的时候展示出来。

1
2
flagSet := goflags.NewFlagSet()
flagSet.SetDescription(`xxx是一款xxx工具`)

我喜欢设置一个选项的结构体,方便命令行参数的传递。

1
2
3
4
5
6
7
8
package types

type Options struct {
SingleReq string
InputFile string
RouteLimitNum int
}

goflags 可以对命令行参数进行分组,更加直观的将不同功能的命令分类,这时就可以将选项结构体与命令参数绑定。

1
2
3
4
5
6
7
8
flagSet.CreateGroup("input", "Input",
flagSet.StringVarP(&options.SingleReq, "req", "r", "", "单个请求"),
flagSet.StringVarP(&options.InputFile, "file", "f", "", "输入文件名称"),
)

flagSet.CreateGroup("limit", "Limit",
flagSet.IntVarP(&options.RouteLimitNum, "limit", "l", 3, "最少路由层数"),
)

如果指定的是一个字符串切片,可以指定对应的分隔符来区分每一个字符串。

1
flagSet.StringSliceVarP(&opt.inputs, "inputs", "i", nil, "list of inputs (file,comma-separated)", goflags.FileCommaSeparatedStringSliceOptions)

指定完所有的参数后需要解析对应参数。

1
2
3
if err := flagSet.Parse(); err != nil {
return nil, fmt.Errorf("Could not parse flags")
}

简单案例如下。

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
package main

import (
"fmt"

"github.com/projectdiscovery/goflags"
)

var options = &types.Options{}

func main() {
_, err := readFlags()
if err != nil {
log.Fatal(err)
}

if len(options.SingleReq) <= 0 {
log.Fatal("No input file")
return
}
return

}

func readFlags() (*goflags.FlagSet, error) {
flagSet := goflags.NewFlagSet()
flagSet.SetDescription(`xxx是一款xxx工具`)

flagSet.CreateGroup("input", "Input",
flagSet.StringVarP(&options.SingleReq, "req", "r", "", "单个请求"),
flagSet.StringVarP(&options.InputFile, "file", "f", "", "输入文件名称"),
)

flagSet.CreateGroup("limit", "Limit",
flagSet.IntVarP(&options.RouteLimitNum, "limit", "l", 3, "最少路由层数"),
)

if err := flagSet.Parse(); err != nil {
return nil, fmt.Errorf("Could not parse flags")
}

return flagSet, nil
}