💻 Почему CLI — это вообще круто?
CLI — это интерфейс командной строки. Звучит немного как что-то из подвала с серверами, но на деле это один из самых полезных форматов программ для разработчика.
CLI-утилиты помогают быстро автоматизировать рутину: создать файлы, обработать данные, запустить проверку, сгенерировать проект, почистить мусор или сделать внутренний инструмент для команды.
И главное — для первой CLI на Go не нужно писать огромный проект. Достаточно одного файла, пары аргументов и желания почувствовать себя человеком, который теперь управляет терминалом, а не страдает от него 😄
🧩 Что мы сделаем?
Напишем простую утилиту с командой greet. Она будет принимать имя и выводить приветствие.
go run main.go greet AlexРезультат:
Привет, Alex 👋Да, это маленький пример. Но именно с таких штук начинается путь к своим генераторам проектов, деплой-скриптам и внутренним инструментам.
⚙️ Шаг 1. Создаём проект
Создадим папку проекта и инициализируем Go-модуль:
mkdir mycli
cd mycli
go mod init mycliТеперь создаём файл main.go. В нём будет вся логика нашей первой CLI-утилиты.
🧠 Шаг 2. Читаем аргументы из терминала
В Go есть пакет os. Через os.Args можно получить всё, что пользователь написал после команды запуска.
package main
import (
"fmt"
"os"
)
func main() {
args := os.Args
fmt.Println(args)
}Запустим:
go run main.go hello worldПрограмма выведет примерно такой список:
[.../main hello world]Здесь важно понять:
args[0]— путь к запущенной программе;args[1]— первый аргумент;args[2]— второй аргумент;и так далее.
То есть если пользователь пишет greet Alex, мы можем отдельно получить команду greet и имя Alex.
🚀 Шаг 3. Делаем свою команду
Теперь добавим нормальную логику. Если пользователь ввёл команду greet, программа поздоровается.
package main
import (
"fmt"
"os"
)
func main() {
args := os.Args
if len(args) < 3 {
fmt.Println("Использование: greet <имя>")
return
}
command := args[1]
name := args[2]
if command == "greet" {
fmt.Printf("Привет, %s 👋\n", name)
} else {
fmt.Println("Неизвестная команда")
}
}Проверяем:
go run main.go greet MaxПолучаем:
Привет, Max 👋В этот момент можно официально сказать: у нас есть своя CLI-команда. Маленькая, но уже рабочая. Терминал начинает уважать 😎
🛡️ Почему нужна проверка len(args)?
Если пользователь забудет передать аргументы, программа может упасть с ошибкой. Например, мы попытаемся обратиться к args[2], которого не существует.
Поэтому сначала проверяем длину списка аргументов:
if len(args) < 3 {
fmt.Println("Использование: greet <имя>")
return
}Это простая защита от классического сценария: «я ничего не ввёл, а программа почему-то взорвалась».
📥 Шаг 4. Работаем с вводом пользователя
CLI-утилита может не только принимать аргументы, но и спрашивать данные прямо во время работы.
Для этого используем bufio.NewReader и os.Stdin:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Как тебя зовут? ")
name, _ := reader.ReadString('\n')
fmt.Printf("Привет, %s", name)
}Теперь программа задаёт вопрос и ждёт ответ. Это уже не просто команда, а маленький интерактивный инструмент.
📤 Шаг 5. Делаем вывод приятнее
Даже в терминале важен UX. Никто не запрещает сделать вывод понятным и живым.
fmt.Println("🚀 Запуск CLI...")
fmt.Println("✅ Готово")
fmt.Println("📦 Файл создан")Хороший CLI не заставляет пользователя гадать, что происходит. Он сообщает статус, ошибки и результат.
⚠️ Обработка ошибок — чтобы не было боли
Новички часто пишут так:
name, _ := reader.ReadString('\n')Для учебного примера это нормально. Но в реальном проекте лучше проверять ошибку:
name, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Ошибка чтения ввода:", err)
return
}Потому что программа без обработки ошибок — это как баг в пятницу вечером. Вроде работает, но тревожно.
📦 Шаг 6. Собираем CLI в отдельный файл
Пока мы запускали программу через go run. Но Go умеет собирать полноценный исполняемый файл.
go build -o mycliТеперь можно запускать так:
./mycli greet AlexВот теперь это уже не просто код из туториала. Это отдельная утилита, которую можно использовать, передавать, добавлять в скрипты и даже положить в системный путь.
🧪 Мини-проект: команда для создания заметки
Давайте сделаем пример чуть полезнее. CLI будет принимать текст заметки и сохранять его в файл.
package main
import (
"fmt"
"os"
)
func main() {
args := os.Args
if len(args) < 3 {
fmt.Println("Использование: note <текст заметки>")
return
}
command := args[1]
text := args[2]
if command != "note" {
fmt.Println("Неизвестная команда")
return
}
err := os.WriteFile("note.txt", []byte(text), 0644)
if err != nil {
fmt.Println("Ошибка сохранения заметки:", err)
return
}
fmt.Println("✅ Заметка сохранена в note.txt")
}Запуск:
go run main.go note "Разобраться с CLI на Go"После этого появится файл note.txt. Маленькая автоматизация, но уже полезная.
🧰 Когда стоит использовать библиотеки?
Для первой CLI достаточно стандартной библиотеки Go. Но если проект растёт, можно подключить специальные пакеты.
Cobra — мощная библиотека для CLI в стиле
git,dockerи других серьёзных инструментов.urfave/cli — удобный вариант для более простых CLI-приложений.
Но не стоит начинать с тяжёлой артиллерии. Сначала пойми базу: аргументы, ввод, вывод, ошибки, сборка. А уже потом можно навешивать флаги, подкоманды и автодополнение.
📱 Где практиковаться, чтобы не бросить через два дня?
Самая частая проблема в обучении программированию — не сложность языка, а хаос. Сегодня посмотрел видео про Go, завтра прыгнул в Python, послезавтра открыл Rust и понял, что жизнь больше не будет прежней.
В приложении Кодик можно учиться программированию структурно и через практику: проходить темы постепенно, писать код, закреплять материал и видеть прогресс.
А ещё есть Telegram-сообщество Кодика, где выходят полезные посты, разборы и подсказки. Это удобный способ повторять программирование без ощущения, что ты один на один с бесконечным интернетом.
CLI — это когда терминал перестаёт быть страшной чёрной дырой и становится твоим личным пультом управления. 🚀
