Go的`flag`包可以打印用法吗?

huangapple go评论88阅读模式
英文:

Can Go's `flag` package print usage?

问题

我可以帮你翻译这段内容:

我能否自定义Go的flag包,以便打印自定义的使用说明字符串?我有一个应用程序,当前的输出如下:

Usage of ./mysqlcsvdump:
  -compress-file=false: 是否压缩连接
  -hostname="": 数据库主机
  -outdir="": 输出存储位置
  -password="": 数据库密码
  -port=3306: 数据库端口
  -single-transaction=true: 是否将所有操作包装在一个事务中
  -skip-header=false: 是否包含列标题
  -user="root": 数据库用户

我希望得到以下形式的输出:

Usage: ./mysqlcsvdump [options] [table1 table2 ... tableN]

参数:
  -compress-file=false: 是否压缩连接
  -hostname="": 数据库主机
  -outdir="": 输出存储位置
  -password="": 数据库密码
  -port=3306: 数据库端口
  -single-transaction=true: 是否将所有操作包装在一个事务中
  -skip-header=false: 是否包含列标题
  -user="root": 数据库用户
英文:

Is it possible for me to customize Go's flag package so that it prints a custom usage string? I have an application with current output

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

and would rather have something like

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

答案1

得分: 119

是的,你可以通过修改flag.Usage来实现:

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

Usage函数会向标准错误输出打印一个使用说明其中包含所有定义的命令行标志该函数是一个变量可以更改为指向自定义函数的指针

`flag`之外的示例用法

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

Yes, you can do that by modifying flag.Usage:

> var Usage = func() {
> fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
>
> flag.PrintDefaults()
> }
>
> Usage prints to standard error a usage message documenting all defined
> command-line flags. The function is a variable that may be changed to
> point to a custom function.

Example use from outside of flag:

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

答案2

得分: 6

如果您想完全自定义您的使用方式,您需要通过使用flag.VisitAll()来重新实现flag.Usage()函数来遍历所有解析的标志。例如:

flag.Usage = func() {
    fmt.Fprintf(os.Stderr, "自定义帮助 %s:\n", os.Args[0])
    
    flag.VisitAll(func(f *flag.Flag) {
        fmt.Fprintf(os.Stderr, "    %v\n", f.Usage) // f.Name, f.Value
    })
}

这段代码将自定义帮助信息输出到标准错误流,并遍历所有解析的标志,打印它们的使用方式。

英文:

If you want full customisation over your usage, you need to reimplement the flag.Usage() function by using flag.VisitAll() to iterate through all the parsed flags. For example:

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

得分: 6

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

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

(参见 flag.go

因此,如果你想自定义你的 flag 使用方式,请不要假设使用 os.Stderr,而是使用类似以下的方式:

flag.Usage = func() {
    w := flag.CommandLine.Output() // 可能是 os.Stderr,但不一定是

    fmt.Fprintf(w, "使用方式:%s ...自定义前导... \n", os.Args[0])

    flag.PrintDefaults()

    fmt.Fprintf(w, "...自定义尾声... \n")

}
英文:

In Feb 2018, Go 1.10 updated the default destination of flag output:

> The default Usage function now prints its first line of output to
> CommandLine.Output() instead of assuming os.Stderr, so that the usage
> message is properly redirected for clients using
> CommandLine.SetOutput.

(see also flag.go)

So if you want to customize your flag usage, don't assume os.Stderr, instead use something like:

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

}

答案4

得分: 1

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

// Output返回用于输出用法和错误消息的目标。如果未设置output或设置为nil,则返回os.Stderr。
func (f *FlagSet) Output() io.Writer {
if f.output == nil {
return os.Stderr
}
return f.output
}

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

英文:

And finally, in Go 1.16.4 we have:

// 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
}

So, by default it uses os.Stderr, otherwise what was set to the output.

huangapple
  • 本文由 发表于 2014年5月19日 03:22:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/23725924.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定