Основы автоматизации и сценариев 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) мы рассмотрим отладку скриптов и многое другое. наслаждайтесь!