---
title: "Знакомство с Cobra: зачем нужен CLI-фреймворк"
description: "Cobra — go-фреймворк для CLI: анатомия командной строки на примерах kubectl и gh, команды, флаги и аргументы, сравнение со flag и первый код."
course: "Cobra: CLI-приложения на Go"
url: "https://golangmaster.ru/courses/cobra/lessons/01-znakomstvo-cobra/"
published: "2026-09-19"
updated: "2026-09-21"
minutes: 16
---

# Знакомство с Cobra: зачем нужен CLI-фреймворк

*Курс «Cobra: CLI-приложения на Go», урок 1 из 25. ~16 минут. Обновлено 21.09.2026. Источник: https://golangmaster.ru/courses/cobra/lessons/01-znakomstvo-cobra/*

Cobra — go-фреймворк для командной строки: на нём написаны kubectl, Hugo и GitHub CLI, и в этом уроке разберём, зачем он нужен, из чего состоит консольная утилита и чем Cobra отличается от стандартного пакета flag.

Откройте терминал и наберите kubectl get pods -n prod --watch. За долю секунды kubectl разберёт эту строку: get — подкоманда, pods — её аргумент, -n и --watch — флаги, один со значением, другой без. Потом он напечатает справку, если вы ошиблись, дополнит имя подкоманды по Tab и молча проглотит любой порядок флагов. Ничего из этого не имеет отношения к Kubernetes — это работа CLI-фреймворка. Написать разбор строки руками на os.Args можно: срез строк, switch по первому элементу, вложенный switch внутри него. Но к третьей подкоманде в коде заводится собственный мини-парсер, к пятой — самодельная справка, а к седьмой вы ловите себя на том, что пишете kubectl в миниатюре вместо своей задачи. Cobra закрывает именно эту рутину — и сейчас разберём, как она устроена и зачем её вообще отделять от бизнес-логики.

### Что такое Cobra: go-библиотека CLI и её история

Cobra — CLI-фреймворк для Go: библиотека, которая берёт на себя разбор командной строки, дерево подкоманд, справку и автодополнение. Написал её Стив Франсия (Steve Francia, ник spf13) в 2013 году — тот же человек за год до этого создал генератор сайтов Hugo, а позже руководил developer relations в Docker и Google. Проект годами живёт в версии 1.x: API стабилен настолько, что примеры из туториалов пятилетней давности компилируются без правок. Код лежит в github.com/spf13/cobra, а рядом живёт Viper — библиотека конфигурации от того же автора; в реальных CLI они часто ходят парой, и в этом курсе мы до неё тоже дойдём. За эти годы Cobra стала стандартом де-факто: когда в Go-команде встаёт вопрос «как делать CLI», ответ по умолчанию — она же, и собеседования спрашивают ровно про это. У Cobra две ипостаси, которые новички часто путают: сама библиотека и генератор каркасов cobra-cli — отдельная утилита, которая по одной команде создаёт готовый проект. С генератором познакомимся во втором уроке, пока важен словарь.

### Кто написан на Cobra

- Kubernetes — kubectl целиком построен на Cobra: get, apply, describe и десятки других подкоманд
- GitHub CLI (gh) — pr, issue, repo: три уровня дерева команд на одном фреймворке
- Hugo — генератор статических сайтов, родной брат Cobra: автор у обоих один и тот же
- Docker CLI — клиент docker переехал на Cobra вместе с системой плагинов
- rclone, etcd, Twitch CLI — список проектов на сайте Cobra давно перевалил за сотню

### Анатомия CLI: команда, подкоманда, флаг, аргумент

Возьмём строку посложнее: gh pr create --title «Правки в API» --base main 42. Слева направо: gh — исполняемый файл, то, что нашлось в PATH; pr — подкоманда первого уровня; create — подкоманда второго уровня; 42 — позиционный аргумент, его смысл определяется только местом в строке; --title и --base — флаги со значениями, их порядок можно менять как угодно. Этот словарь — фундамент курса, проговорим его чётко. Команды задают глагол: что делать. Аргументы — объект: над чем делать. Флаги — настройки: как именно делать. Сильные консольные утилиты соблюдают это правило почти религиозно: в git commit -m «сообщение» команда — commit, флаг -m несёт текст. Если пользователь вашей утилиты должен угадывать, что значит третий параметр подряд, — это баг дизайна, а не сложность предметной области.

### Минимальная программа на Cobra, которую будем разбирать

```go
package main

import (
        "fmt"
        "os"

        "github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
        Use:   "hello",
        Short: "Приветствие из первого урока",
        Run: func(cmd *cobra.Command, args []string) {
                fmt.Println("Привет, CLI!")
        },
}

func main() {
        if err := rootCmd.Execute(); err != nil {
                os.Exit(1)
        }
}
```

Вся программа — одна переменная rootCmd типа *cobra.Command. Поле Use задаёт имя команды, Short — однострочное описание для справки, Run — функцию, которая выполнится при запуске. Execute() читает os.Args, находит нужную команду и вызывает её Run; при ошибке возвращается error, и os.Exit(1) отдаёт скриптам код выхода, отличный от нуля.

### Что общего у kubectl, Hugo и gh

Сядьте за любой из этих инструментов — и первые минуты пройдёте без документации, потому что все они ведут себя одинаково. gh --help печатает список подкоманд с однострочными описаниями; gh pr --help разворачивает подробности уже про pr. hugo server --port 1313 понимает флаг и до, и после имени подкоманды. kubectl на опечатку отвечает подсказкой Did you mean this?. Это не копирование чужого стиля — это Cobra, у которой контракт пользователя встроен в библиотеку: справка генерируется на каждом уровне дерева, у флагов есть шорткаты (-n и --namespace — один и тот же флаг), шелл получает автодополнение через встроенную команду completion, версия печатается по --version. Пользователь вашей утилиты получит привычное поведение бесплатно, а вы выбросите из плана сорок разборов os.Args. Заодно унифицируется мелочь, которую никто не любит писать руками: --version у корня, поведение при пустом вызове, чтение конфига до первой команды. Каждый пункт по отдельности — полчаса работы и вечный спор «а как у нас принято?»; в Cobra они просто есть.

### Cobra против пакета flag

Стандартная библиотека Go умеет парсить флаги пакетом flag, и на одном уровне он хорош: определить flag.String, вызвать flag.Parse — готово. Ограничения всплывают сразу за этим уровнем. Дерева команд нет: подкоманды придётся перебирать вручную по os.Args и для каждой заводить свой FlagSet. Справка генерируется только списком флагов — ни однострочных описаний подкоманд, ни развёрнутых Long-текстов. Автодополнения и подсказок при опечатках нет вообще. Нюанс, о котором забывают: под капотом Cobra работает не flag, а pflag — его форк с POSIX-семантикой: формы --flag=value, объединение шорткатов -abc в один вызов, флаги до и после позиционных аргументов. flag с этим справляется хуже. Если у вас уже есть код на flag, миграция обычно начинается с замены flag.String на cmd.Flags().String — семантика почти совпадает, ломаться нечему. Мой вывод после утилит на обоих: flag — для скриптов и инструментов с одной командой, Cobra — как только нарисовалась вторая подкоманда. Это не религия, а точка окупаемости: дерево и справка в Cobra описываются декларативно, руками — итеративно и со скрипом.

### flag и Cobra: что приходится писать самому

| Задача | flag | Cobra |
| --- | --- | --- |
| Дерево подкоманд | нет — только вручную по os.Args | AddCommand и готовая маршрутизация |
| Справка --help | список флагов по умолчанию | генерируется по Use, Short, Long, Example |
| Автодополнение bash/zsh | нет | встроенная команда completion |
| Подсказка при опечатке | нет | Did you mean this? из коробки |
| Хуки до и после команды | нет | PreRun, PostRun и их персистентные версии |
| Привязка конфигурации | нет | штатная связка с Viper |

> **Cobra и cobra-cli — два разных инструмента.** Библиотека github.com/spf13/cobra попадает в go.mod каждого вашего проекта. cobra-cli — генератор каркасов: ставится один раз на машину и нужен только чтобы создать файлы проекта и добавить заготовки подкоманд. В коде приложений cobra-cli не упоминается.

### Когда Cobra не нужна

Честности ради: не каждая утилита заслуживает фреймворк. Если программа принимает пару флагов, у неё одна точка входа, а справка помещается в абзац README — берите flag или читайте os.Args напрямую: лишняя зависимость в go.mod не нужна. Мой водораздел такой: появилась вторая подкоманда или справка перестала влезать в одну строку — время Cobra. Вторая ситуация, где я обходился без неё, — утилиты внутри монорепозитория со своим запускачом и конфигом: там от CLI нужны только флаги, и flag хватает с запасом. Спорная часть: некоторые тянут Cobra и для однострочников ради красивой справки. Я так не делаю — сборка дольше, пользы ноль, — но если в команде есть готовый шаблон проекта, цена стремится к нулю, и тогда возражений нет.

### Как устроен курс и что понадобится

Курс практический: с третьего урока в голове держим один проект — CLI-менеджер задач, который к финалу обрастёт конфигами, цветным выводом и тестами. Одна оговорка про формат: браузерная песочница сайта исполняет чистый Go без файловой системы и os.Args, поэтому Cobra-код в уроках не запускается онлайн — примеры нужно гонять локально с установленным Go, а интерактивы в песочнице остаются разминкой на синтаксис. Если сам Go у вас пока на уровне «читал, но не писал», начните с [базового курса](/courses/go-basics/): структуры, ошибки и пакеты понадобятся уже на второй неделе. И настройтесь на интерактивы в каждом уроке — тесты, пропуски и карточки засчитывают XP и заодно работают повторением: тезис, который не отложился, всплывёт в вопросе раньше, чем вы его забудете.

### Проверка: анатомия командной строки

**Вопрос:** В вызове gh pr create --title «Правки» 42 что такое 42?

- Флаг без значения
- ✅ Позиционный аргумент подкоманды create
- Подкоманда третьего уровня
- Значение флага --title

42 стоит после имени команды без своего флага — это позиционный аргумент: его смысл задаётся только местом. Значением --title здесь является «Правки», а pr и create — подкоманды.

### Проверка: flag или Cobra

**Вопрос:** Что из перечисленного умеет Cobra, но не умеет пакет flag?

- Объявить строковый флаг со значением по умолчанию
- Распарсить флаги из os.Args
- ✅ Сгенерировать справку по дереву подкоманд и команду completion для шелла
- Напечатать сообщение в терминал

Флаги со значениями и разбор os.Args — работа flag, она у него есть. Дерево подкоманд с автогенерируемой справкой и автодополнение — территория Cobra.

### Что напечатает программа без аргументов

```go
package main

import (
        "fmt"

        "github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
        Use:   "hello",
        Short: "Приветствие из первого урока",
        Run: func(cmd *cobra.Command, args []string) {
                fmt.Println("Привет, CLI!")
        },
}

func main() {
        rootCmd.Execute()
}
```

**Что выведет программа?**

- ✅ Привет, CLI!
- Справку с именем hello и строкой Short
- Ничего: аргументов нет, Run не вызывается
- Ошибку: без аргументов Execute падает

Execute разбирает os.Args, находит корневую команду и вызывает её Run — пустой список аргументов ему не помеха. Справка печатается по -h или --help, а количество аргументов мы начнём валидировать в четвёртом уроке.

### Восстановите минимальную Cobra-программу

Впишите имя пакета, путь импорта фреймворка, имя команды в Use и тип команды.

```go
package ___

import "github.com/spf13/___"

var rootCmd = &cobra.Command{
        Use: "___",
        Run: func(cmd *cobra.___, args []string) {},
}

func main() {
        rootCmd.Execute()
}
```

Подсказка: Пакет для исполняемого файла — main; библиотека живёт в github.com/spf13/cobra; тип каждой команды — cobra.Command.

Правильные ответы в пропусках: `main`, `cobra`, `hello`, `Command`

### Соберите каркас из шести строк

Расставьте строки от объявления пакета до вызова Execute.

Правильный порядок строк:

1. `package main`
2. `import "github.com/spf13/cobra"`
3. `var rootCmd = &cobra.Command{Use: "hello"}`
4. `func main() {`
5. `  rootCmd.Execute()`
6. `}`

### Карточки: словарь CLI и Cobra

- **Cobra** — CLI-фреймворк для Go (2013, Стив Франсия): дерево команд, справка, автодополнение, хуки. Библиотека github.com/spf13/cobra.
- **cobra-cli** — Генератор каркасов: создаёт проект и заготовки подкоманд. Ставится отдельно через go install, в рантайме не участвует.
- **Подкоманда** — Именованный глагол в дереве команд: get у kubectl, pr у gh. В Cobra — тоже *cobra.Command, привязанный через AddCommand.
- **Позиционный аргумент** — Значение после имени команды без своего флага: pods в kubectl get pods. Смысл определяется позицией.
- **Флаг** — Именованная настройка со значением или без: --port 1313, -n prod. Порядок флагов не важен.
- **pflag** — Форк пакета flag с POSIX-семантикой (--flag=value, склейка -abc), на котором построен разбор флагов в Cobra.

### Что дальше

Во втором уроке поставим Cobra и сгенерируем первый проект: cobra-cli init, структура main.go и cmd/root.go, первый запуск. Третий урок — [дерево команд](/courses/cobra/lessons/03-komandy-podkomandy/): rootCmd, AddCommand и справка, ради которой всё затевалось. Потом пойдут [флаги](/courses/cobra/lessons/05-flogy-localnye/) — локальные и персистентные, они заслуживают отдельного урока, потому что в CLI их больше всего. Финал курса — [CLI-менеджер задач](/courses/cobra/lessons/25-itogovyj-proekt/), куда сложится всё пройденное. Пока подготовьте площадку: убедитесь, что go version отвечает, и освободите вечер — с четверти часа на второй урок уйдёт только на установку.

## Коротко: что запомнить

- Cobra — CLI-фреймворк Go: дерево команд, справка, автодополнение и хуки в одной библиотеке.
- На Cobra написаны kubectl, Hugo, GitHub CLI и Docker CLI — у всех один пользовательский контракт.
- Словарь курса: команда — глагол, аргумент — объект, флаг — настройка.
- flag парсит флаги одной программы; Cobra добавляет дерево, справку, подсказки и completion, работая поверх pflag.
- Cobra и cobra-cli — разные вещи: библиотека в каждом проекте, генератор — один раз на машину.
- Для утилиты с парой флагов Cobra избыточна; моя точка входа — вторая подкоманда.
- Код курса запускается локально: песочница сайта Cobra не исполняет.

## Домашнее задание

Вспомните три CLI, которыми пользуетесь каждый день: git, docker, kubectl — что угодно. Для каждого выпишите две подкоманды, один позиционный аргумент и два флага, один со значением, другой без. Затем откройте справку каждой утилиты через --help и проверьте, что подкоманды показаны с однострочными описаниями. Этот словарь пригодится в четвёртом уроке, где будем решать, аргумент перед нами или флаг.

## Вопросы и ответы по уроку

### Что такое Cobra в Go простыми словами?

Библиотека, которая снимает с разработчика рутину консольной утилиты: разбор строки запуска, дерево подкоманд, справку --help, автодополнение и подсказки при опечатках. Вы описываете команды и пишете только их логику.

### Чем Cobra лучше стандартного flag?

flag умеет парсить флаги одной программы. Cobra добавляет дерево подкоманд, многоуровневую справку, автодополнение для шеллов, хуки PreRun и PostRun, подсказки опечаток. Для утилиты с подкомандами разница огромна.

### Нужно ли знать Go, чтобы пройти курс?

Да, на базовом уровне: функции, структуры, ошибки. Если это пока в стадии чтения, начните с курса «Go с нуля» — код Cobra-проектов опирается на структуры и методы с самых первых уроков.
