Go 可以走';s`flag`包装印刷用途?

Go 可以走';s`flag`包装印刷用途?,go,Go,我是否可以自定义Go的标志包,以便它打印自定义使用字符串?我有一个电流输出的应用程序 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: dat

我是否可以自定义Go的
标志
包,以便它打印自定义使用字符串?我有一个电流输出的应用程序

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

是的,您可以通过修改:

用法将打印一条用法消息,记录所有已定义的 命令行标志。函数是一个变量,可以更改为 指向自定义函数

标志外部使用的示例

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

如果希望对使用情况进行完全自定义,则需要通过使用
flag.VisitAll()
迭代所有解析的标志来重新实现
flag.usage()
函数。例如:

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
    })
}
2018年2月,更新了
标志的默认目标
输出:

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

(另见)

因此,如果您想自定义标记的用法,请不要假设
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")

}

最后,在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
,否则将设置为输出。

就个人而言,我更喜欢这个包,而不是标准标志,它更健壮,更符合其他语言:。你应该试一试。无耻的插件:和另一个用于Go的“命令行处理器”包:@topkip Go中丰富的替代命令行解析器,令人遗憾的是,突出了标准解析器的不足。标准
标志
包适用于此项目。当我有一个稍微复杂一点的CLI应用程序要使用时,我会看看您的备选方案。不过,谢谢!另一个是Cobra:当前的
标志.Usage
默认实现写入
CommandLine.Output()
,而不是
os.Stderr
,这允许您使用
flag.CommandLine.SetOutput(io.Writer)
标志.CommandLine.Output()对其进行设置
获取
标志设置为的当前
io.Writer
。因此,使用
fmt.Fprintf(flag.CommandLine.Output(),…)
确保目标输出的一致性。
// 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
}