Форматирование shell-скриптов с помощью shfmt
Quick Links
- Что такое shfmt?
- Установка shfmt
- Использование shfmt
- Практическое применение и интеграция
- В каких случаях shfmt не заменит проверку ошибок
- Заключение
Что такое shfmt?
shfmt — это форматтер, парсер и частичный интерпретатор для shell-скриптов, разработанный Dustin Krysak. Проект размещён на GitHub и поддерживает POSIX, Bash и mksh. Поскольку инструмент написан на Go, он быстрый, кроссплатформенный и не ограничивается только Bash.
Краткое определение: shfmt автоматически приводят содержание shell-файлов к единому стилю, что облегчает чтение и ревью кода.

Установка shfmt
Ниже перечислены безопасные и простые способы установки. Выберите подходящий вашему окружению.
- Snap (Ubuntu, Mint и другие snap-enabled дистрибутивы):
sudo snap install shfmt- RedHat / CentOS / Fedora (DNF + snapd):
Примечание: после установки snapd может потребоваться перезагрузка или выход/вход в сессию.
sudo dnf install snapd
sudo snap install snap-store
sudo snap install shfmtНа RHEL/CentOS возможно потребуется подключить репозиторий EPEL перед установкой snapd.
- macOS (Homebrew):
brew install shfmt- Установка из исходников через Go (если установлен Go):
go install mvdan.cc/sh/v3/cmd/shfmt@latestВажно: сохраняйте пути к бинарям (GOBIN / GOPATH/bin) в PATH, если устанавливаете через go install.
Использование shfmt
После установки можно запустить shfmt для форматирования отдельных файлов или целых директорий. Основные и безопасные опции:
- -i N — задать ширину отступа в пробелах (0 = табы)
- -w — записать результат обратно в файлы (in-place)
- -d — показать diff форматирования
- -l — вывести список файлов, которые требуют форматирования
- -s — упрощать конструкцию там, где это возможно
Пример: форматирование файла с двумя пробелами отступа и перезапись файла:
shfmt -i 2 -w test.shПример: показать diff, не меняя файл:
shfmt -d test.shПример: найти все неотформатированные файлы в каталоге рекурсивно:
shfmt -l -w .Пример: неотформатированный файл
Пусть у нас есть файл test.sh с несколькими проблемами (см. исходный пример):
#!/bin/bash__
echo 'not well formatted line 1'
echo 'not well formatted line 2'
echo 'this line has extra spaces on the end > '
func() {
echo 'more unneeded spaces'
echo 'way out'
}
func ()Здесь видны проблемы: лишние пробелы, неверный вызов функции (func () — это синтаксис определения, не вызова), и неправильный shebang с двойным подчёркиванием.
Выполнение:
shfmt test.shДаст диагностическое сообщение, которое укажет на несогласованность в синтаксисе — например, shfmt может ожидать тело функции, если видит name () и затем {.

Когда мы исправим вызов функции (уберём скобки у вызова) и запустим shfmt с нужными опциями, мы получим аккуратно отформатированный скрипт.

Обратите внимание: shfmt форматирует код и помогает заметить некоторые синтаксические странности, но он не заменяет полноценный статический анализатор.

В примере выше shfmt не сигнализировал об одном из багов — невалидном shebang #!/bin/bash__. Для таких задач используют инструмент shellcheck.
Практическое применение и интеграция
shfmt хорошо подходит для автоматизации форматирования в разных условиях. Ниже — готовые подходы и чеклист внедрения.
Быстрые команды (cheat sheet)
- Форматирование и перезапись файла:
shfmt -i 2 -w script.sh- Просмотр отличий без изменения:
shfmt -d script.sh- Список файлов, требующих форматирования:
shfmt -l **/*.sh- Рекурсивное форматирование текущей папки и поддиректорий:
shfmt -w .Pre-commit hook (пример)
Добавьте в .git/hooks/pre-commit или используйте pre-commit framework следующую команду, чтобы не допускать неотформатированных файлов в репозиторий:
#!/bin/sh
echo "Running shfmt..."
shfmt -i 2 -w
git add -AИдея: автоматически исправлять формат до коммита.
Интеграция в CI
В CI-пайплайне полезно запускать shfmt -d или shfmt -l и завершать сборку с ошибкой, если найдены несформатированные файлы. Это гарантирует единый стиль во всём проекте.
Пример в псевдокоде CI шага:
# Стадия линтинга
shfmt -l .
if [ $? -ne 0 ]; then
echo "Run shfmt -w to fix formatting"
exit 1
fiРольовые чеклисты при внедрении
Разработчик:
- Установить shfmt локально
- Настроить editor integration (VS Code, Vim, JetBrains) или pre-commit
- Прогнать shfmt перед PR
Ревьюер:
- Проверять, что CI не пропустил несформатированные файлы
- Отклонять PR с изменениями, содержащими только форматирование, если нет согласованного правила
DevOps/инженер CI:
- Добавить проверку shfmt в pipeline
- Обеспечить единообразие версии shfmt в окружениях (docker image или версия в CI)
В каких случаях shfmt не заменит проверку ошибок
- Логические ошибки и неправильный shebang (например,
#!/bin/bash__) shfmt может не обнаружить. - Неправильное использование команд, ошибочная обработка ошибок или небезопасные практики shfmt не исправляет.
- shfmt не проверяет Семантику: он заботится о синтаксисе и стиле, а не о корректности алгоритма.
Для поиска багов используйте shellcheck и unit-тестирование скриптов (например, bats-core).
Когда shfmt не подойдёт: примеры и альтернативы
- Если вы хотите строго следовать особому стилю, несовместимому с shfmt — придётся выбирать другой инструмент или настраивать правила в команде.
- Для глубокой статической проверки используйте shellcheck.
- Для сложных преобразований AST-уровня могут понадобиться кастомные парсеры или написание анализаторов на основе bash-parser.
Методология принятия решения (мини-SOP)
- Оцените используемые оболочки в проекте: POSIX, Bash, mksh.
- Проверьте совместимость shfmt с целевыми shell-диалектами.
- Выберите формат отступов (таб или N пробелов).
- Внедрите shfmt локально + pre-commit.
- Добавьте проверку в CI (shfmt -l или -d).
- Обучите команду и зафиксируйте правило в CONTRIBUTING.md.
Контроль качества и тесты приемки
Критерии приёмки:
- Все shell-файлы в репозитории форматируются командой shfmt -i 2 -w без конфликтов.
- CI падает, если shfmt -l находит файлы.
- Pre-commit устраняет несоответствия формата локально.
Тест-кейсы:
- Запустить shfmt на корректном файле — отличий быть не должно.
- Запустить shfmt на целевой директории с файлами, содержащими неряшливый стиль — команда должна перезаписать их (с -w) и/или показать diff (с -d).
Практические советы и эвристики
- Если команда не договорилась о табах или пробелах, выберите 2 пробела для компактности или 4 для читабельности. Главное — единообразие.
- Используйте shfmt вместе с shellcheck: первый — для стиля, второй — для логики и потенциальных багов.
- Включите shfmt в pre-commit, чтобы не тратить время ревью на форматирование.
Краткое резюме
shfmt — это простой и мощный инструмент для приведения shell-скриптов к единому стилю. Он ускоряет ревью, уменьшает визуальный шум и помогает выявлять некоторые синтаксические проблемы. Но shfmt не заменяет статический анализ и runtime-тестирование; для этого сочетайте его с shellcheck и автотестами. Внедрение shfmt в workflow (локально, pre-commit, CI) даст наибольшую пользу.
Important: shfmt упрощает жизнь, но не забывайте про тестирование и анализ логики.
Счастливого форматирования!
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента