моя контактная информация
Почтамезофия@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Когда я открыл код k8s, я обнаружил, что в основном основные службы используют библиотеку Cobra в качестве возможности обработки командной строки.Поэтому, чтобы глубже понять процесс обучения коду, давайте сначала напишем демо-версию на основе этой библиотеки, чтобы углубить наше понимание этой библиотеки.
Гитхаб:GitHub - spf13/cobra: Командир для современных взаимодействий Go CLI Вот она, Cobra — это инструмент командной строки, реализованный на языке Go. И сейчас он используется многими проектами, такими как Kubernetes, Hugo и Github CLI и т. д.Используя Cobra, мы можем быстро создавать инструменты командной строки, особенно подходящие для написания测试脚本
, различные услуги Admin CLI
ждать.
Из-за параметров командной строки сам golang поставляется с библиотекой флагов. Как использовать библиотеку флагов?
- flag.Parse()
-
- args := flag.Args()
После разбора каждую команду нужно оценить, что очень хлопотно.
Но когда мы ее используем, нам нужно проводить различный анализ и выводы в командной строке, но с помощью этой библиотеки мы можем уменьшить этот избыточный код.
Без лишних слов, давайте прямо объясним, как использовать этот проект. Моя среда находится на Macos.
Выполнение командной строки
go get -u github.com/spf13/cobra@latest
$ go install github.com/spf13/cobra-cli@latest
Поскольку я уже создал каталог bin в своем пути к коду golang, поэтому после выполнения этой команды все выглядит следующим образом:
Мы увидели исполняемый файл cobra-cli.
Здесь мы можем использовать эту штуку в команде для ее инициализации.Коллективные шаги заключаются в следующем:
- xxx@MBP src % mkdir greet
- xxx@MBP src % cd greet
- xxx@MBP test % ls
- xxx@MBP greet % cobra-cli init
- Error: Please run `go mod init <MODNAME>` before `cobra-cli init`
- xxx@MBP greet % go mod init greet
- go: creating new go.mod: module greet
- xxx@MBP greet % ls
- go.mod
- xxx@MBP greet % cobra-cli init
- Your Cobra application is ready at
- /Users/XXX/workspace/golang/src/greet
- xxx@MBP greet % ls
- LICENSE cmd go.mod go.sum main.go
- xxx@MBP greet %
Первым шагом является создание тестового каталога, затем выполнение теста инициализации go mod, а затем выполнение командной строки инициализации cobra-cli, после чего будет создан файл леса.
В каталоге будут созданы следующие файлы:
- main.go cmd LICENSE go.mod go.sum
- ├── LICENSE
- ├── cmd
- │ └── root.go
- └── main.go
- go.mod
- go.sum
Только что созданный файл может оказаться бесполезным, поскольку в нем нет конкретных параметров команды, поэтому мы продолжаем выполнять и добавляем командное слово.
cobra-cli add [command]
Таким образом он сгенерирует еще один файл.
Например, выполните
cobra-cli добавить приветствие
- // Package cmd /*
- package cmd
-
- import (
- "fmt"
-
- "github.com/spf13/cobra"
- )
-
- // greetCmd represents the greet command
- var greetCmd = &cobra.Command{
- Use: "greet",
- Short: "A brief description of your command",
- Long: `A longer description that spans multiple lines and likely contains examples
- and usage of using your command. For example:
-
- Cobra is a CLI library for Go that empowers applications.
- This application is a tool to generate the needed files
- to quickly create a Cobra application.`,
- Run: func(cmd *cobra.Command, args []string) {
- // 这段代码是我加的。
- if len(args) < 1 {
- cmd.Help()
- return
- }
- name := args[0]
- fmt.Println("greet called:", name)
- },
- }
-
- func init() {
- rootCmd.AddCommand(greetCmd)
-
- // Here you will define your flags and configuration settings.
-
- // Cobra supports Persistent Flags which will work for this command
- // and all subcommands, e.g.:
- // greetCmd.PersistentFlags().String("foo", "", "A help for foo")
-
- // Cobra supports local flags which will only run when this command
- // is called directly, e.g.:
- greetCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
- }
Таким образом, мы видим, что команда приветствия добавлена.
Затем мы компилируем его и генерируем целевой файл, а затем выполняем следующую команду:
- ./greet
-
- A longer description that spans multiple lines and likely contains
- examples and usage of using your application. For example:
-
- Cobra is a CLI library for Go that empowers applications.
- This application is a tool to generate the needed files
- to quickly create a Cobra application.
-
- Usage:
- greet [command]
-
- Available Commands:
- completion Generate the autocompletion script for the specified shell
- greet A brief description of your command
- help Help about any command
- mockMsg A brief description of your command
-
- Flags:
- -h, --help help for greet
- -t, --toggle Help message for toggle
-
- Use "greet [command] --help" for more information about a command.
-
Из возвращенного выше содержимого мы видим, что существует дополнительная подкоманда gree.
И вы можете добавить флаг, например -h
Вышеуказанный Run может содержать бизнес-логику, которую мы хотим обработать.
Если мы хотим добавить некоторые значения флагов, нам нужно всего лишь добавить следующий код в run
- g, _ := cmd.Flags().GetInt32("goroutine")
- p, _ := cmd.Flags().GetInt32("packet")
- fmt.Println("mockmsg called,flags:g=", g, ",p=", p, ",args:", args)
Например, мы реализуем следующее:
- Run: func(cmd *cobra.Command, args []string) {
- if len(args) < 1 {
- cmd.Help()
- return
- }
- name := args[0]
- fmt.Println("greet called:", name)
-
- g, _ := cmd.Flags().GetInt32("goroutine")
- p, _ := cmd.Flags().GetInt32("packet")
- fmt.Println("mockmsg called,flags:g=", g, ",p=", p, ",args:", args)
- },
Таким образом, его можно использовать следующим образом
- ./greet greet xx -p 10 -g 100
- greet called: xx
- greetCmd called,flags:g= 100 ,p= 10 ,args: [xx]
-
В основном я просматривал код модуля kubctl и обнаружил, что этот модуль имеет более богатую инкапсуляцию cmd для поддержки более сложных сценариев.
Среди них мы начнем с главного kubectl
метод входа
- // NewDefaultKubectlCommand creates the `kubectl` command with default arguments
- func NewDefaultKubectlCommand() *cobra.Command {
- ioStreams := genericiooptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}
- return NewDefaultKubectlCommandWithArgs(KubectlOptions{
- PluginHandler: NewDefaultPluginHandler(plugin.ValidPluginFilenamePrefixes),
- Arguments: os.Args,
- ConfigFlags: defaultConfigFlags().WithWarningPrinter(ioStreams),
- IOStreams: ioStreams,
- })
- }
Поскольку kubectl может обрабатывать файлы и флаги, для этой ситуации необходимо установить различные параметры. Мы обнаружили, что каждое поле в структуре cmd полностью использовано.
Эти два метода являются основными методами, которые по сути инициализируются и назначаются структуре команды.
- // NewDefaultKubectlCommandWithArgs creates the `kubectl` command with arguments
- func NewDefaultKubectlCommandWithArgs(o KubectlOptions) *cobra.Command {
- cmd := NewKubectlCommand(o)
Среди них NewKubectlCommand используется для новых экземпляров cmd.
- func NewKubectlCommand(o KubectlOptions) *cobra.Command {
- warningHandler := rest.NewWarningWriter(o.IOStreams.ErrOut, rest.WarningWriterOptions{Deduplicate: true, Color: term.AllowsColorOutput(o.IOStreams.ErrOut)})
- warningsAsErrors := false
- // Parent command to which all subcommands are added.
- cmds := &cobra.Command{
- Use: "kubectl",
Здесь мы видим использование команд kubectl. Поскольку в этой статье в основном говорится об использовании команд, мы не будем вдаваться в подробности о других командах get k8s, я расскажу об этом в следующей статье.
Ниже приводится подробное объяснение конкретных связанных полей команды.
以下是对 `Command` 结构体中每个字段的详细解释:
- 1. `Use`:这是一个字符串,用于描述命令的基本使用方式。它规定了命令所需的参数和可选参数的格式,为用户提供了简洁明了的使用指导。
- - 例如:`"add [-F file | -D dir]... [-f format] profile"` 表示 `add` 命令可以有可选的 `-F` 和 `-D` 参数,其中 `-F` 后跟一个文件,`-D` 后跟一个目录,这两个参数是互斥的,并且可以多次出现,还有一个可选的 `-f` 参数后跟格式信息,最后需要一个 `profile` 参数。
-
- 2. `Aliases`:一个字符串切片,存储了该命令的别名。这使得用户可以通过不同的名称来调用同一个命令,增加了命令使用的灵活性。
- - 比如:`["add_item", "insert"]` 是 `add` 命令的别名。
-
- 3. `SuggestFor`:也是一个字符串切片,其中包含了此命令可能被建议替代的其他命令名称。这有助于在用户输入类似但不完全准确的命令时提供相关的建议。
-
- 4. `Short`:一个简短的字符串,用于在帮助输出中提供命令的简短描述,让用户快速了解命令的主要功能。
- - 例如:"添加新的项目"
-
- 5. `GroupID`:指定该子命令在其父命令的“帮助”输出中所属的组标识,便于对命令进行分组展示和管理。
-
- 6. `Long`:详细的长字符串,在“帮助 <此命令>”输出中提供更全面和深入的命令描述,包括更多的功能细节、使用示例、注意事项等。
-
- 7. `Example`:包含命令使用的示例字符串,通过实际的例子帮助用户更好地理解如何正确使用该命令。
-
- 8. `ValidArgs`:一个字符串切片,列出了在外壳自动补全中所有有效的非标志参数。
-
- 9. `ValidArgsFunction`:一个函数,动态地提供有效的非标志参数用于外壳自动补全,是一种更灵活的参数提供方式。
-
- 10. `Args`:定义了预期的参数的相关规则和处理方式。
-
- 11. `ArgAliases`:一个字符串切片,列出了有效参数的别名,这些别名不会在外壳自动补全中被提示,但手动输入时会被接受。
-
- 12. `BashCompletionFunction`:用于传统 Bash 自动补全生成器的自定义 Bash 函数,为特定的 Bash 环境提供定制的自动补全功能。
-
- 13. `Deprecated`:如果命令已被弃用,存储了使用该命令时将显示的提示信息,告知用户该命令不应再被使用。
-
- 14. `Annotations`:一个键值对映射,允许应用程序为命令添加自定义的标识、分组或特殊选项等元数据。
-
- 15. `Version`:存储命令的版本信息,用于版本控制和显示。
-
- 16. 各种 `Run` 函数:
- - `PersistentPreRun` 和 `PersistentPreRunE`:在命令执行前被调用,且子命令会继承并执行,用于进行一些持久的预处理操作。
- - `PreRun` 和 `PreRunE`:在命令执行前被调用,但子命令不会继承,用于特定于当前命令的预处理。
- - `Run` 和 `RunE`:实际的工作函数,实现命令的主要逻辑。
- - `PostRun` 和 `PostRunE`:在 `Run` 函数执行后被调用,用于进行后续的处理操作。
-
- 17. `commandgroups`:一个指针切片,指向子命令所属的组对象。
-
- 18. `args`:实际从标志解析得到的参数切片。
-
- 19. `flagErrorBuf`:一个字节缓冲区,用于存储来自 `pflag` 的错误消息。
-
- 20. `flags`:一个 `flag.FlagSet` 对象,包含了所有的标志。
-
- 21. `pflags`:存储持久的标志。
-
- 22. `lflags`:本地标志的缓存,用于优化 `LocalFlags` 函数调用。
-
- 23. `iflags`:继承的标志的缓存,用于优化相关函数调用。
-
- 24. `parentsPflags`:父命令的所有持久标志。
-
- 25. `globNormFunc`:一个全局的标准化函数,用于处理标志名称的标准化。
-
- 26. `usageFunc`:用户定义的使用函数,用于自定义命令的使用说明。
-
- 27. `usageTemplate`:用户定义的使用模板。
-
- 28. `flagErrorFunc`:用户定义的标志错误处理函数。
-
- 29. `helpTemplate`:用户定义的帮助模板。
-
- 30. `helpFunc`:用户定义的帮助函数。
-
- 31. `helpCommand`:具有“帮助”用途的命令,如果用户未定义,则使用默认的帮助命令。
-
- 32. `helpCommandGroupID`:帮助命令所属的组标识。
-
- 33. `completionCommandGroupID`:自动完成命令所属的组标识。
-
- 34. `versionTemplate`:用户定义的版本模板。
-
- 35. `errPrefix`:用户定义的错误消息前缀。
-
- 36. `inReader`:用户定义的输入读取器,替代标准输入。
-
- 37. `outWriter`:用户定义的输出写入器,替代标准输出。
-
- 38. `errWriter`:用户定义的错误输出写入器,替代标准错误输出。
-
- 39. `FParseErrWhitelist`:要忽略的标志解析错误的列表。
-
- 40. `CompletionOptions`:用于控制外壳自动完成的选项。
-
- 41. `commandsAreSorted`:一个布尔值,指示命令切片是否已排序。
-
- 42. `commandCalledAs`:一个结构体,记录命令被调用时的名称和是否被调用的状态。
-
- 43. `ctx`:上下文对象,用于传递和管理命令执行的上下文信息。
-
- 44. `commands`:一个指针切片,包含此命令支持的子命令。
-
- 45. `parent`:指向该命令的父命令的指针。
-
- 46. `Max lengths` 相关字段:记录命令相关字符串的最大长度,用于格式化和展示。
-
- 47. `TraverseChildren`:一个布尔值,决定是否在执行子命令之前解析所有父命令的标志。
-
- 48. `Hidden`:如果为真,该命令将在可用命令列表中隐藏,不向用户显示。
-
- 49. `SilenceErrors`:一个布尔值,用于控制是否静默处理错误。
-
- 50. `SilenceUsage`:一个布尔值,用于控制在发生错误时是否静默使用信息。
-
- 51. `DisableFlagParsing`:如果为真,将禁用标志解析,所有标志将作为参数传递给命令。
-
- 52. `DisableAutoGenTag`:如果为真,在生成文档时将禁用自动生成的标签。
-
- 53. `DisableFlagsInUseLine`:如果为真,将在使用行中禁用标志的添加。
-
- 54. `DisableSuggestions`:如果为真,将禁用基于编辑距离的建议功能。
-
- 55. `SuggestionsMinimumDistance`:定义显示建议的最小编辑距离,必须大于 0 。
Эта статья в основном представляет собой пошаговое объяснение того, как использовать библиотеку Cobra. Когда мы используем эту библиотеку, мы можем лучше понять принцип ее работы, а затем основываясь на том, как использовать конкретные k8 и использование определенных полей. полностью раскрыть возможности и ценность cmd