Can Go的'flag`包打印用法?

时间:2014-05-18 19:22:23

标签: go

我是否可以自定义Go的flag包,以便打印自定义用法字符串?我有一个带有当前输出的应用程序

Usage of ./mysqlcsvdump:
  -compress-file=false: whether compress connection or not
  -hostname="": database host
  -outdir="": where output will be stored
  -password="": database password
  -port=3306: database port
  -single-transaction=true: whether to wrap everything in a transaction or not.
  -skip-header=false: whether column header should be included or not
  -user="root": database user

并且宁愿拥有像

这样的东西
Usage: ./mysqlcsvdump [options] [table1 table2 ... tableN]

Parameters:
  -compress-file=false: whether compress connection or not
  -hostname="": database host
  -outdir="": where output will be stored
  -password="": database password
  -port=3306: database port
  -single-transaction=true: whether to wrap everything in a transaction or not.
  -skip-header=false: whether column header should be included or not
  -user="root": database user

4 个答案:

答案 0 :(得分:62)

是的,您可以通过修改flag.Usage

来实现
var Usage = func() {
        fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])

        flag.PrintDefaults()
}
     

用法将标记所有已定义的用法消息打印到标准错误   命令行标志。该函数是一个可以更改为的变量   指向自定义功能。

flag以外的使用示例:

flag.Usage = func() {
    fmt.Fprintf(os.Stderr, "This is not helpful.\n")
}

答案 1 :(得分:1)

最后,在 Go 1.16.4 中,我们有:

// Output returns the destination for usage and error messages. os.Stderr is returned if
// output was not set or was set to nil.
func (f *FlagSet) Output() io.Writer {
    if f.output == nil {
        return os.Stderr
    }
    return f.output
}

因此,默认情况下它使用 os.Stderr,否则设置为输出。

答案 2 :(得分:0)

如果要完全自定义用法字符串,则需要重新实现flag.Usage函数,还可以使用flag.VisitAll()遍历已解析的标志,而不使用PrintDefault():

flag.Usage = func() {
    fmt.Fprintf(os.Stderr, "Custom help %s:\n", os.Args[0])

    flag.VisitAll(func(f *flag.Flag) {
        fmt.Fprintf(os.Stderr, "    %v\n", f.Usage) // f.Name, f.Value
    })
}

答案 3 :(得分:-1)

2018 年 2 月,Go 1.10 更新了 flag 输出的默认目标:

<块引用>

默认 Usage 函数现在将其第一行输出打印到 CommandLine.Output() 而不是假设 os.Stderr,这样用法 使用客户端正确重定向消息 CommandLine.SetOutput。

(另见flag.go

因此,如果您想自定义标志用法,请不要假设 os.Stderr,而是使用以下内容:

flag.Usage = func() {
    w := flag.CommandLine.Output() // may be os.Stderr - but not necessarily

    fmt.Fprintf(w, "Usage of %s: ...custom preamble... \n", os.Args[0])

    flag.PrintDefaults()

    fmt.Fprintf(w, "...custom postamble ... \n")

}