Поиск по сайту:

Как использовать shfmt для лучшего форматирования сценариев оболочки


Да, форматирование необходимо и очень помогает в понимании сложного кода. Однако для тех, кто часто пишет сценарии оболочки, двойная проверка форматирования может стать утомительной задачей. Эта статья покажет вам, как сократить работу с помощью shfmt!

Что такое шфмт?

Shfmt, разработанный Дастином Крисаком, представляет собой средство форматирования, синтаксического анализатора и интерпретатора Shell. Сам проект размещен на GitHub и имеет понятный README и четко представленный репозиторий. Инструмент был разработан на Go и поддерживает оболочки POSIX, Bash и mksh. Это делает shfmt действительно универсальной программой, а не только Bash.

Установка шфмт

Чтобы установить shfmt в ваш дистрибутив Linux с поддержкой snap (например, Ubuntu и Mint), выполните следующую команду в своем терминале:

sudo snap install shfmt

Чтобы установить shfmt в ваш дистрибутив Linux на основе RedHat/Yum (например, RHEL, Centos и Fedora), выполните в терминале следующие команды:

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

sudo dnf install snapd
sudo snap install snap-store
sudo snap install shfmt

В RHEL и Centos вам также может потребоваться сначала установить репозиторий EPEL.

Использование шфмт

После установки пакета snap вы можете начать использовать shfmt.

Давайте определим очень плохо отформатированный и написанный скрипт как 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 в последней строке следует больше скобок. Вызов функции в Bash (а не определение функции) должен иметь только имя, а не скобки. Чуть выше произошло правильное определение функции.

Посмотрим, что об этом думает shfmt.

shfmt test.sh

Хотя вывод выглядит немного загадочным, обратите внимание, что термины foo (используется здесь) и bar (здесь сейчас не используется) часто используются в ИТ-кругах для обозначения/представления любых как идиома или элемент. foo здесь действительно относится к func.

Даже в этом случае сообщение остается немного загадочным, пока мы не поймем, глядя на последнюю строку, что на самом деле происходит начало определения функции (а не вызов функции), потому что были включены две скобки. Это объясняет, почему сообщение говорит нам, что ожидается нечто большее; должен сопровождаться оператором. shmft ищет здесь что-то вроде func(){ some_command[s]; .

Бинго! Это расширяет функциональные возможности shfmt, превращая его в средство проверки/проверки сценариев оболочки, хотя, вероятно, оно и близко не является исчерпывающим, как тот, о котором мы писали при использовании shellcheck для поиска и исправления ошибок сценариев. Тем не менее, очень даже удобно!

Мы исправили нашу ошибку, и теперь входной скрипт 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

Мы снова выполняем shfmt для кода и получаем гораздо более подходящий и хорошо отформатированный вывод:

Большой. Теперь мы можем подняться на один уровень дальше и указать shfmt, что мы хотели бы использовать ширину отступа/табуляции в два пробела вместо полной табуляции. Я всегда пишу код, используя два пробела в качестве ширины отступа/табуляции, и использую дополнительный пробел, когда команда на следующей строке тесно связана с предыдущей, например, продолжение команды и т. д., хотя это случается не часто. За более чем 10 лет я обнаружил, что эти два пространства идеально подходят для личных и общих проектов.

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

Мы установим ширину отступа/табуляции в два пробела, используя параметр -i (который --help определяет как indent: 0 для табуляции (по умолчанию), >0 для количества пробелов): shfmt -i 2 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

Большой! Однако мы отмечаем, что shfmt не уловил нашу преднамеренную ошибку: #!/bin/bash__ неверен и должен читаться как #!/bin/bash вместо этого.

Таким образом, все еще существует вариант использования использования shellcheck для поиска ошибок скриптов, помимо использования shfmt для лучшего форматирования скриптов. Однако, что интересно, в данном конкретном случае даже shellcheck не заметил проблемы. Об этом недостатке было сообщено команде shellcheck, поэтому в свое время это может быть исправлено.

Если вам интересно узнать больше о Linux, вы можете просмотреть серию Bash Automation & Scripting Basics Series, а также циклы Bash: for, while и until Циклы Bash: for, while и until и Экспорт переменных в Bash: the Почему и как статьи.

Подведение итогов

Возможность писать чистые, хорошо отформатированные сценарии без ошибок становится проще, если вы используете инструмент форматирования оболочки, такой как shfmt, и средство проверки ошибок/ошибок, такое как shellcheck. . Даже тогда, как мы видели, некоторые вещи могут остаться незамеченными даже до того момента, когда вы запускаете скрипт в первый раз. shfmt — небольшая, но эффективная утилита, которая поможет вам отформатировать ваши скрипты и код в соответствии с выбранными вами отступами. Наслаждайтесь!