我可以使用Go标志添加命令吗?

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

Can I add commands with Go flags?

问题

我知道我可以像这样定义标志:

  1. initPtr := flag.String("init", "config.json", "使用配置文件名进行初始化")

我会这样调用它:

  1. myapp --init=myconfig.json

不过我想知道是否可以定义类似命令的东西,这样可以这样调用应用程序:

  1. myapp init --filename=myconfig.json
  2. myapp check --filename=myconfig.json
  3. myapp run
英文:

I know I can define flags like this:

  1. initPtr := flag.String("init", "config.json", "Initialize with config filename")

Which I will call like this:

  1. myapp --init=myconfig.json

I wonder though if I can define something like commands so that to call the app like this?

  1. myapp init --filename=myconfig.json
  2. myapp check --filename=myconfig.json
  3. myapp run

答案1

得分: 1

是的,你可以。

请查看https://golang.org/pkg/flag/获取FlagSet文档。

还有一个可工作的示例:https://github.com/constabulary/gb/blob/master/cmd/gb/main.go

以下是miltonb请求的示例:

  1. go run flagset.go init --filename=foo.json foo bar
  2. init foo.json [foo bar]
  3. go run flagset.go check --filename=bar.json 1 2 3
  4. check bar.json [1 2 3]
  5. go run flagset.go run
  6. run
  7. cat flagset.go
  8. package main
  9. import (
  10. "flag"
  11. "fmt"
  12. "os"
  13. )
  14. func main() {
  15. init := flag.NewFlagSet("init", flag.ExitOnError)
  16. initFile := init.String("filename", "myconfig.json", "configuration file")
  17. check := flag.NewFlagSet("check", flag.ExitOnError)
  18. checkFile := check.String("filename", "myconfig.json", "configuration file")
  19. if len(os.Args) <= 1 {
  20. flag.Usage()
  21. os.Exit(1)
  22. }
  23. switch os.Args[1] {
  24. case "init":
  25. if err := init.Parse(os.Args[2:]); err == nil {
  26. fmt.Println("init", *initFile, init.Args())
  27. }
  28. case "check":
  29. if err := check.Parse(os.Args[2:]); err == nil {
  30. fmt.Println("check", *checkFile, check.Args())
  31. }
  32. case "run":
  33. fmt.Println("run")
  34. }
  35. }
英文:

Yes, you can.

Take a look at https://golang.org/pkg/flag/ for FlagSet documentation.

And for a working example: https://github.com/constabulary/gb/blob/master/cmd/gb/main.go

And an example as requested by miltonb:

  1. % go run flagset.go init --filename=foo.json foo bar
  2. init foo.json [foo bar]
  3. % go run flagset.go check --filename=bar.json 1 2 3
  4. check bar.json [1 2 3]
  5. % go run flagset.go run
  6. run
  7. % cat flagset.go
  8. package main
  9. import (
  10. &quot;flag&quot;
  11. &quot;fmt&quot;
  12. &quot;os&quot;
  13. )
  14. func main() {
  15. init := flag.NewFlagSet(&quot;init&quot;, flag.ExitOnError)
  16. initFile := init.String(&quot;filename&quot;, &quot;myconfig.json&quot;, &quot;configuration file&quot;)
  17. check := flag.NewFlagSet(&quot;check&quot;, flag.ExitOnError)
  18. checkFile := check.String(&quot;filename&quot;, &quot;myconfig.json&quot;, &quot;configuration file&quot;)
  19. if len(os.Args) &lt;= 1 {
  20. flag.Usage()
  21. os.Exit(1)
  22. }
  23. switch os.Args[1] {
  24. case &quot;init&quot;:
  25. if err := init.Parse(os.Args[2:]); err == nil {
  26. fmt.Println(&quot;init&quot;, *initFile, init.Args())
  27. }
  28. case &quot;check&quot;:
  29. if err := check.Parse(os.Args[2:]); err == nil {
  30. fmt.Println(&quot;check&quot;, *checkFile, check.Args())
  31. }
  32. case &quot;run&quot;:
  33. fmt.Println(&quot;run&quot;)
  34. }
  35. }

答案2

得分: 1

你可以使用命令行参数和标志的组合来实现这一点。

例如:

  1. configFilePtr := flag.String("filename", "", "配置文件名")
  2. flag.Parse()
  3. n := len(os.Args)
  4. if n > 1 {
  5. switch os.Args[1] {
  6. case "init":
  7. initApp(*configFilePtr)
  8. case "check":
  9. checkApp(*configFilePtr)
  10. case "run":
  11. runApp()
  12. }
  13. }

另一种选择是使用类似于 spf13's cobra 的工具。

更新:

如果你需要根据命令使用不同的标志,你可以使用 FlagSet,就像 Kare Nuorteva 的回答中提到的那样。

例如:

  1. f1 := flag.NewFlagSet("f1", flag.ContinueOnError)
  2. silent := f1.Bool("silent", false, "")
  3. f2 := flag.NewFlagSet("f2", flag.ContinueOnError)
  4. loud := f2.Bool("loud", false, "")
  5. switch os.Args[1] {
  6. case "apply":
  7. if err := f1.Parse(os.Args[2:]); err == nil {
  8. fmt.Println("apply", *silent)
  9. }
  10. case "reset":
  11. if err := f2.Parse(os.Args[2:]); err == nil {
  12. fmt.Println("reset", *loud)
  13. }
  14. }

参考资料:

英文:

You can do that using a combination of command line arguments and flags.

Eg.

  1. configFilePtr := flag.String(&quot;filename&quot;, &quot;&quot;, &quot;Config Filename&quot;)
  2. flag.Parse()
  3. n := len(os.Args)
  4. if n &gt; 1 {
  5. switch os.Args[1] {
  6. case &quot;init&quot;:
  7. initApp(*configFilePtr)
  8. case &quot;check&quot;:
  9. checkApp(*configFilePtr)
  10. case &quot;run&quot;:
  11. runApp()
  12. }
  13. }

Another option is using something like spf13&#39;s cobra.

Update :

If you require the use of different flags as per command you can use a FlagSet as mentioned in Kare Nuorteva's answer.

Eg.

  1. f1 := flag.NewFlagSet(&quot;f1&quot;, flag.ContinueOnError)
  2. silent := f1.Bool(&quot;silent&quot;, false, &quot;&quot;)
  3. f2 := flag.NewFlagSet(&quot;f2&quot;, flag.ContinueOnError)
  4. loud := f2.Bool(&quot;loud&quot;, false, &quot;&quot;)
  5. switch os.Args[1] {
  6. case &quot;apply&quot;:
  7. if err := f1.Parse(os.Args[2:]); err == nil {
  8. fmt.Println(&quot;apply&quot;, *silent)
  9. }
  10. case &quot;reset&quot;:
  11. if err := f2.Parse(os.Args[2:]); err == nil {
  12. fmt.Println(&quot;reset&quot;, *loud)
  13. }
  14. }

Reference

huangapple
  • 本文由 发表于 2017年1月12日 03:32:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/41599244.html
匿名

发表评论

匿名网友

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

确定