Как использовать пакет Cobra в Go

    Команда Simple-Server
    03.06.2026
    13 мин

    Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.

    Кратко о задаче

    Cobra — это полноценная CLI-платформа для языка Go, в состав которой входит два базовых компонента:

    • Библиотека для создания современных CLI-приложений
    • CLI-инструмент для быстрого создания приложений на основе стандартных (для Cobra) файлов-обработчиков команд

    Кстати, Cobra был разработан одним из членов команды Go, Стивом Франсом (spf13), изначально для проекта Hugo — специального фреймворка для создания веб-сайтов. Спустя время Cobra стала одним из самых популярных пакетов Golang.

    Cobra предоставляет ряд довольно простых функций для создания современных интерфейсов командной строки. Помимо этого в Cobra есть высокоуровневый контроллер, помогающий организовать код разрабатываемого CLI-приложения.

    • Иерархию обработки команд
    • Мощный анализ аргументов и флагов
    • Иерархию флагов (глобальные и локальные)
    • Проверку подкоманд
    • Совместимость со стандартом POSIX
    • Автоматическое создание справки для команд и флагов

    Кстати, такие крупные проекты, как Kubernetes , Hugo или CockroachDB имеют кодовую базу на Golang и для обработки команд используют именно пакет Cobra.

    CLI-команды имеют довольно стандартную схему:

    {приложение} {кодкоманда} [аргументы] [--флаги и их параметры]

    Например, команды в реальных проектах могут выглядеть как-то так:

    kubectl get all -n kube-system

    Рабочие сущности можно поделить на три типа — все они так или иначе репрезентируют структуру команд в консольном терминале:

    • Команды (Commands). Указывают на конкретные действия, которые необходимо выполнить. Впрочем, как в и любом классическом CLI-приложении.
    • Аргументы (Args). Это некоторые вещи или сущности, которые передаются в команду, после чего она работает с ними и возвращает результат.
    • Флаги (Flags). Короткие модификаторы команд (то есть конкретных действий), которые вносят определенные корректировки в выполнение работ и влияют на конечный результат работы CLI-приложения.

    Немного о POSIX-совместимости

    В стандарте POSIX есть соглашение о паттерне (схеме) организации аргументов и флагов, которому должны следовать CLI-приложения.

    Это тот самый классический формат, с которым знакомо большинство разработчиков — многочисленные служебные программы Linux (например, «ls», «cp», «useradd») и сторонние приложения следуют именно ему.

    Важно помнить, что схема команд четко формализована в стандарте и представляет собой следующий вид:

    имя_приложения [-a] [-b] [-c аргумент] [-d|-e]

    У каждого приложения может быть несколько версий одной и той же опции — длинная и короткая. При этом есть четкое правило, что короткая версия должна состоять только из одного символа.

    На всякий случай проверьте наличие компилятора Golang в вашей системе. Это можно сделать с помощью команды запроса версии:

    Если Golang действительно установлен, то в консоли появится версия Go и короткое название операционной системы.

    Далее мы создадим отдельный каталог под наш Cobra-проект:

    После этого перейдем в него:

    Golang имеет свои особенности в работе его модульной системы, необходимой для подключения пакетов. Поэтому предварительно директорию с проектом необходимо проинициализировать с помощью специальной команды:

    После этого каталог превратится в полноценный модуль Go — в консоли появится соответствующее сообщение о создании модуля с именем CobraProject.

    2. Подключение пакета Cobra

    Начиная с версии Go 1.18 в Golang существует специальная команда go install, автоматически выполняющая установку удаленных модулей.

    Поэтому мы воспользуемся именно ей, загрузив пакет Cobra из официального репозитория на github:

    go install github.com/spf13/cobra-cli@latest

    Обратите внимание, что в конце есть указатель latest — мы устанавливаем самый последний релиз.

    В терминале нам станет доступен исполняемый файл cobra-cli. С помощью него мы инициализируем проект Cobra в нашем рабочей каталоге — к этому моменту вы должны находиться уже в нем:

    После этого в рабочем каталоге появятся файлы, содержащие некий стандартный код пакета Cobra с названием проекта — CobraProject.

    Структура файлов будет иметь следующий вид:

    CobraProject/ cmd/ root.go main.go go.mod go.sum

    Файл main.go является входной точкой (entry point) в CLI-приложение. Его стандартное содержимое примерно такое:

    package main import ( "CobraProject/cmd" // путь может отличаться в зависимости от расположения рабочей директории ) func main() { cmd.Execute() }

    Все команды размещаются в виде отдельных файлов в каталоге /cmd. При этом файл root.go является корневым обработчиком команд — по сути это базовая команда любого консольного интерфейса.

    Например, рассмотрим следующую команду:

    Здесь go является корневой командой, которая обрабатывается root.go, get — дочерняя команда, обработчик которой размещен в отличном от root.go файле.

    Для сборки CLI-приложения используется та же самая команда, что и для создания обычного двоичного файла проекта Go:

    Стандартно исполняемый файл появится в рабочем каталоге проекта.

    Чтобы использовать собранное CLI-приложение, его также необходимо установить:

    После этого CLI-приложение станет доступно для вызова из терминала командной строки. Чтобы воспользоваться им достаточно написать в консоль название проекта:

    Если все работает корректно, то в консоле появится стандартный вывод для команды без параметров. Разумеется, в дальнейшем стандартный вывод можно будет изменять — это делается в файле root.go.

    3. Создание функции для команды

    Каждая введенная в консоль команда вызывает соответствующую функцию Go, которая выполняет логику этой команды. При этом любые параметры и флаги, указанные в консоли, передаются в функцию.

    В качестве простого примера мы реализуем небольшую функцию, которая отсчитывает время в текущем часовом поясе. Для этого мы задействуем пакет time.

    После инициализации CLI в рабочем каталоге должна была появиться директория cmd. Перейдем в нее:

    Теперь создадим файл, который будет содержать нашу функцию:

    package cmd // указываем название нашего пакета import "time" // импортируем стандартный пакет времени Go func getTimeFromZone(zone string) (string, error) { loc, err := time.LoadLocation(zone) // узнаем текущую локацию // проверяем на ошибку if err != nil { return "", err // возвращаем пустой результат с данными об ошибке } timeNow := time.Now().In(loc) // получаем текущее время на основе локации return timeNow.Format(time.RFC1123), nil // возвращаем отформатированный результат без данных об ошибке }

    Как можно видеть, функция возвращает два значения — результат и данные о возможной ошибке.

    4. Добавление команды в CLI

    Теперь, когда функциональная часть нашего приложения готова, мы можем «зарегистрировать» команду в CLI-приложении для доступа извне.

    Для этого существует отдельная команда add:

    cobra-cli add timefromzone

    После этого в папке cmd появится файл timefromzone.go со стандартным кодом внутри.

    Кстати, в этой же папке у вас уже расположен файл root.go отвечающий за «корневую» обработку команды — то есть команды без каких-либо параметров.

    Несложно догадаться, что «обработчики» консольных команд формируются в файловой системе операционной системы в виде отдельных go-исходников.

    Давайте откроем новый файл и наполним его следующим кодом:

    package cmd import ( "fmt" "log" "github.com/spf13/cobra" ) var timefromzoneCmd = &cobra.Command { Use:   "timefromzone", Short: "Возвращает время из заданной географической зоны", Long: `Команда возвращает время из заданной географической зоны. Принимает только один аргумент — зона, время которой необходимо узнать. Результат возвращается в формате стандарта RFC1123.`, Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { timefromzone:= args[0] timeNow, err := getTimeFromZone(timefromzone) if err != nil { log.Fatalln("Неверная временная зона") } fmt.Println(timeNow) }, } func init() { rootCmd.AddCommand(timefromzoneCmd) // добавляем новую команду к корневой команде }

    Разберемся, что означает каждое поле:

    • Use. Название, под которым будет доступна команда из терминала
    • Short. Краткое описание команды, которое будет доступно пользователю из консоли
    • Long. Полное описание команды, которое будет доступно пользователю из консоли
    • Args. Точное количество аргументов, необходимое для работы команды
    • Run. Функция-обработчик, внутри которой мы вызываем и обрабатываем ранее созданную функцию getTimeFromZone.

    На самом деле в некоторых случаях вы могли бы упростить кодовую базу, написав нужную логику прямо внутри функции-обработчика команды:

    import "time" var timefromzoneCmd = &cobra.Command { Use:   "timefromzone", Short: "Возвращает время из заданной географической зоны", Long: `Команда возвращает время из заданной географической зоны. Принимает только один аргумент — зона, время которой необходимо узнать. Результат возвращается в формате стандарта RFC1123.`, Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { zone := args[0] loc, err := time.LoadLocation(zone) if err != nil { log.Fatalln("Временная зона указана неверно") } fmt.Println(time.Now().In(loc).Format(time.RFC1123)) }, }

    Все! Команда добавлена. Остается только заново переустановить наше CLI-приложение:

    Теперь мы можем обратиться к нашему приложению через консоль, указав название команды и передав в качестве аргумента кодовое имя часового пояса:

    CobraProject timefromzone Europe/Moscow

    Консольный вывод будет примерно таким:

    Fri, 10 Nov 2023 22:41:06 Europe/Moscow

    Кстати, полный список существующих часовых поясов и их кодовые названия можно посмотреть на соответствующей странице в Википедии.

    5. Добавление флагов в CLI

    Как правило, при выполнении консольных помимо параметров можно также указывать флаги.

    Флаги — это опции, которые вносят некоторые изменения в поведение конкретных команд. Флаг легко определить по предшествующему ему дефису (или двух).

    Наличие флагов в CLI-приложении добавляет вариативность и гибкость в поведение команд. Без флагов пришлось бы создавать множество сложных функций с большим количеством повторяющегося кода.

    В этом смысле флаги позволяют унифицировать консольное приложение. При этом в Cobra флаги можно поделить на два условных типа:

    • Локальные. Действуют только в рамках конкретной команды.
    • Постоянные. Могут применяться сразу ко всем командам и их подкомандам.

    Давайте перейдем в ранее созданный файл timefromzone.go и изменим в конце функцию инициализации, добавив обработку флагов:

    func init() { rootCmd.AddCommand(timefromzoneCmd) // добавили выше определенную команду к корневой команде timefromzoneCmd.Flags().String("format", "", "Выводит время в формате yyyy-mm-dd") // добавили флаг к выше определенной команде, указав информацию о нем }

    Теперь мы можем воспользоваться флагом в функции Run определенной команды. В этом случае полный код файла timefromzone.go окажется таким:

    package cmd import ( "fmt" "time" "github.com/spf13/cobra" ) var timefromzoneCmd = &cobra.Command { Use:   "timefromzone", Short: "Возвращает время из заданной географической зоны", Long: `Команда возвращает время из заданной географической зоны. Принимает только один аргумент — зона, время которой необходимо узнать. Результат возвращается в формате стандарта RFC1123.`, Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { var date string zone := args[0] loc, _ := time.LoadLocation(zone) fla, _ := cmd.Flags().GetString("format") if fla != "" { date = time.Now().In(loc).Format(fla) } else { date = time.Now().In(loc).Format(time.RFC1123) } fmt.Printf("Текущее время в часовом поясе %v: %v\n", loc, date) }, } func init() { rootCmd.AddCommand(timefromzoneCmd) timefromzoneCmd.Flags().String("format", "", "Выводит время в формате yyyy-mm-dd") }

    Повторно переустановим наше CLI-приложение:

    И выполним созданную команду, но уже с флагом:

    CobraProject timefromzone Europe/Moscow --format 2006-01-02

    Теперь за счет флага команда «видит» явно указанный формат даты (ГГГГ-ММ-ДД) и выводит следующий результат:

    Текущее время в часовом поясе Europe/Moscow: 2023.11.10

    Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.

    VPS для проекта

    VPS с root-доступом, NVMe и поддержкой 24/7 на Simple-Server.

    StarterVDS

    490₽

    в месяц

    1 ядро

    1 ГБ RAM

    20 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Безлимитный трафик
    Заказать VPS
    Рекомендуем

    PerformanceVDS

    1190₽

    в месяц

    2 ядра

    4 ГБ RAM

    60 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Базовая DDoS-защита
    Заказать VPS

    Нужна другая конфигурация или чистый VPS без панели?

    Все тарифы VPS

    Похожие статьи, которые могут быть вам интересны