Гид по технологиям

Форматирование shell-скриптов с помощью shfmt

• 5 min read • Инструменты • Обновлено 29 Nov 2025
Форматирование shell-скриптов с shfmt
Форматирование shell-скриптов с shfmt

Quick Links

  • Что такое shfmt?
  • Установка shfmt
  • Использование shfmt
  • Практическое применение и интеграция
  • В каких случаях shfmt не заменит проверку ошибок
  • Заключение

Что такое shfmt?

shfmt — это форматтер, парсер и частичный интерпретатор для shell-скриптов, разработанный Dustin Krysak. Проект размещён на GitHub и поддерживает POSIX, Bash и mksh. Поскольку инструмент написан на Go, он быстрый, кроссплатформенный и не ограничивается только Bash.

Краткое определение: shfmt автоматически приводят содержание shell-файлов к единому стилю, что облегчает чтение и ревью кода.

Логотип shfmt и пример отступов

Установка 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 применил отступ в 2 пробела и отформатировал файл

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

Shebang с ошибкой, которую 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)

  1. Оцените используемые оболочки в проекте: POSIX, Bash, mksh.
  2. Проверьте совместимость shfmt с целевыми shell-диалектами.
  3. Выберите формат отступов (таб или N пробелов).
  4. Внедрите shfmt локально + pre-commit.
  5. Добавьте проверку в CI (shfmt -l или -d).
  6. Обучите команду и зафиксируйте правило в 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 упрощает жизнь, но не забывайте про тестирование и анализ логики.

Счастливого форматирования!

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро