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

Zty*_*tyx 42 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
Run Code Online (Sandbox Code Playgroud)

宁愿有类似的东西

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
Run Code Online (Sandbox Code Playgroud)

nem*_*emo 76

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

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

        flag.PrintDefaults()
}
Run Code Online (Sandbox Code Playgroud)

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

从外面使用的示例flag:

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

  • 当前的`flag.Usage`默认实现写入`CommandLine.Output()`而不是`os.Stderr`,它允许你用`flag.CommandLine.SetOutput(io.Writer)设置它. (5认同)
  • `flag.CommandLine.Output()` 获取 `flag` 包设置的当前 `io.Writer`。因此,使用“fmt.Fprintf(flag.CommandLine.Output(), ...)”可确保一致的目标输出。 (2认同)

col*_*tor 7

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")

}
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您想完全自定义您的使用情况,则需要通过使用迭代所有已解析的标志来重新实现该flag.Usage()函数。flag.VisitAll()例如:

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
    })
}
Run Code Online (Sandbox Code Playgroud)