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

Основы автоматизации и сценариев Bash (часть 2)


Bash — это идеальная оболочка и язык программирования, позволяющий создавать высококачественные сценарии автоматизации. Во второй части серии мы рассмотрим плотность кода, встроенные комментарии и правильное заключение переменных в одинарные или двойные кавычки.

Основы автоматизации и сценариев Bash

Если вы еще этого не сделали и только начинаете работать с Bash, прочитайте нашу статью «Автоматизация Bash и основы создания сценариев, часть 1». Это вторая статья в нашей серии из трех частей, посвященных автоматизации Bash и основам написания сценариев. В сегодняшней статье мы рассмотрим, помимо прочего, плотность кодирования Bash и ее связь с предпочтениями разработчиков. В связи с этим мы также рассмотрим встроенные комментарии.

Как только мы начинаем создавать небольшие скрипты, исследовать переменные и работать с текстовыми строками, мы быстро понимаем, что может существовать концептуальная разница между одинарными и двойными кавычками. Есть, и во второй теме ниже мы углубимся в это.

Плотность и лаконичность кода Bash

Язык программирования Bash может быть очень плотным и кратким, но он также может быть объемным и многословным. Это в значительной степени зависит от предпочтений разработчика.

Например, следующий код Bash:

true || echo 'untrue'

Что можно прочитать как Ничего не делать, и сделать это успешно (код выхода 0), и если это не удастся (вы можете прочитать идиому Bash || как ИЛИ), выведите текст 'untrue ', также может быть записано как:

if [ ! true ]; then
  echo 'untrue'
fi

Что делает код немного другим, но в основном делает то же самое.

Это, в свою очередь, может быть прочитано как Если true не является (обозначается идиомой !) true, тогда выведите текст «untrue».

Оба мини-скрипта приводят к одному и тому же пустому выводу, поскольку true не равно untrue.

Множество команд и инструментов, доступных (или устанавливаемых) из командной строки и в ней, еще больше увеличивают возможное смещение между хорошо читаемыми сценариями и трудным для понимания, плотным и кратким кодом.

В то время как приведенные выше примеры короткие и относительно простые для понимания, когда вы создаете длинный однострочный код (термин, часто используемый разработчиками Bash для обозначения фрагмента кода, состоящего из нескольких команд, написанных в одной строке), использующий многие из таких команд , по сравнению с более подробным сценарием, разница становится более очевидной. Учитывать:

V="$(sleep 2 & fg; echo -n '1' | sed 's|[0-9]|a|')" && echo "${V}" | sed 's|[a-z]|2|g' || echo 'fail'

Это типичный однострочный скрипт Bash, который использует команды sleep, fg, echo и sed как а также различные идиомы и регулярные выражения Bash, чтобы в основном спать 2 секунды, выводить текст и преобразовывать этот текст с помощью регулярных выражений. Сценарий также регулярно проверяет условия/результаты предыдущих команд, используя идиомы Bash || (если не удается, выполните следующие действия) и && (в случае успеха сделайте следующее)

Я перевел это с приблизительным соответствием функционала более полному сценарию с некоторыми изменениями. Например, мы поменяли местами наш fg (переместите команду sleep, помещенную в фоновый режим, обратно на передний план и подождите, пока она завершится как обычные нефоновые процессы) на wait, который будет ожидать завершения PID спящего режима (запущенного с помощью eval и захваченного с помощью идиомы Bash $!).

#!/bin/bash

CMD="sleep 2"
eval ${CMD} &
wait $!
EXIT_CODE=${?}

V="$(echo -e "${CMD}n1" | sed 's|[0-9]|a|')"

if [ ${EXIT_CODE} -eq 0 ]; then
  echo "${V}" | sed 's|[a-z]|2|g'
  EXIT_CODE=${?}
  if [ ${EXIT_CODE} -ne 0 ]; then
    echo 'fail'
  fi
fi

Большая разница! И это всего лишь один разработчик, который пишет это по-своему. Код Bash, написанный другими, имеет тенденцию быть несколько сложным для чтения, и эта сложность быстро увеличивается с плотностью и лаконичностью. Тем не менее, разработчик уровня эксперта в Bash быстро поймет даже очень плотный и лаконичный код, написанный другими, за некоторыми исключениями, например регулярными выражениями.

Чтобы узнать больше о написании регулярных выражений, ознакомьтесь с Как изменить текст с помощью регулярных выражений с помощью редактора sed Stream.

Из этих примеров становится ясно, что ваш пробег со временем будет меняться. Однако в целом, когда вы начинаете разрабатывать скрипты Bash, рекомендуется дружить с одноранговыми программистами (путем написания легко читаемого кода).

Если вам нужно создать плотный и краткий код, вы можете предоставить множество встроенных комментариев. Строка с префиксом # считается строкой комментария/примечания, а символ # можно использовать даже в конце строки после любой исполняемой команды, чтобы опубликовать сообщение. суффиксный комментарий, поясняющий команду, условный оператор и т. д. Например:

# This code will sleep one second, twice
sleep 1  # First sleep
sleep 1  # Second sleep

Одинарные кавычки или двойные кавычки?

В Bash текст в одинарных кавычках () воспринимается интерпретатором Bash как обычный текст, тогда как текст в двойных кавычках (\) интерпретируется (анализируется) Bash. Хотя разница в том, как все работает, может быть не сразу понятна из этого определения, следующий пример показывает нам, что происходит, когда мы заменяем на \ и наоборот:

echo ' $(echo "Hello world") '
echo " $(echo 'Hello world') "

В первом примере текст $ (echo \Hello world\) воспринимается как обычный текст, поэтому вывод будет просто $ (echo \Hello world\) \) . Однако во втором примере вывод будет Hello world .

Интерпретатор Bash проанализировал текст в двойных кавычках, чтобы увидеть, найдет ли он какие-либо специальные идиомы Bash, на которые можно воздействовать. Одна из таких идиом была найдена в $ ( ... ), которая в основном запускает подоболочку и выполняет все, что находится между идиомами ( ... ). Думайте об этом как о оболочке внутри оболочки — подоболочке — выполняющей все, что вы передаете ей, как совершенно новую команду. Вывод любой такой команды или команд затем передается обратно в оболочку верхнего уровня и вставляется точно в то место, где была запущена подоболочка.

Таким образом, наша подоболочка выполнила echo Hello world, результатом которого является Hello world. Как только это было сделано, подоболочка завершилась, и текст Hello world был вставлен вместо вызова подоболочки $ ( ... ) (подумайте об этом как обо всех код $ ( ... ) заменяется любым выводом, созданным подоболочкой.

Результатом для верхней оболочки является следующая команда: echo \Hello world\, результатом которой, как мы видели, является Hello world .

Обратите внимание, что мы заменили двойные кавычки внутри подоболочки на одинарные. Это не обязательно! Можно было бы ожидать увидеть ошибку синтаксического анализа, когда команда использует синтаксис echo\...\...\... \, в котором вторые двойные кавычки заканчивали бы первый, за которым следует еще один тест, что приводит к ошибке. Однако это не так.

И это не потому, что Bash гибок со строками в кавычках (например, он вполне успешно принимает echo test\More test\test), а потому, что подоболочка сама по себе является оболочкой, и таким образом, внутри подоболочки можно использовать двойные кавычки. Докажем это на дополнительном примере:

echo "$(echo "$(echo "more double quotes")")"

Это будет работать нормально и приведет к выводу больше двойных кавычек. Каждая из двух вложенных подоболочек (работающих в основной оболочке, из которой вы выполняете это) по очереди принимает двойные кавычки, и ошибки не генерируются, даже если несколько двойных кавычек вложены в общую однострочную команду. Это демонстрирует некоторые возможности программирования Bash.

В итоге

Изучив плотность кодирования, мы осознаем ценность написания хорошо читаемого кода. Если, тем не менее, нам нужно сделать плотный и краткий код, мы можем добавить множество встроенных комментариев, используя #, чтобы улучшить читабельность. Мы рассмотрели одинарные и двойные кавычки и то, как существенно различается их функциональность.

Мы также кратко рассмотрели встроенные комментарии в сценариях, а также функциональность подоболочки при выполнении из строки, заключенной в двойные кавычки. Наконец, мы увидели, как подоболочка может использовать другой набор двойных кавычек, не влияя тем самым на двойные кавычки, используемые на более высоком уровне.

В Bash Automation and Scripting Basics (часть 3) мы рассмотрим отладку скриптов и многое другое. наслаждайтесь!