ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE)
Понедельник, 31 марта, 2025
Сегодня у нас 1 праздник:
Международный День Резервного Копирования (World Backup Day). Пользователи сайта социальных новостей reddit предложили сделать дату 31.03 Международным днём резервного копирования, аргументируя это тем, что никогда заранее нельзя узнать, какие сюрпризы преподнесёт 1.04

Расширение команды Bash

Bash Heredoc

В командной строке или в сценариях оболочки есть три основных способа взаимодействия команд друг с другом. Первый и второй способ — через файловый ввод-вывод через каналы и среду. Третий способ — через параметр команды. Однако, чтобы команда могла взаимодействовать с другой через параметры, она или ее результат должны быть включены в список параметров. Вот где в игру вступает расширение команд или подстановка команд. Здесь мы рассмотрим все, что вам нужно знать о подстановке команд, чтобы писать сценарии bash, как босс!

 

Подстановка команд

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

 

Синтаксис

Есть два приемлемых синтаксиса или способов выполнения подстановки команд в bash:

  1. синтаксис знака доллара; и
  2. синтаксис обратной кавычки.

 

На данный момент оба пути представлены без нашего мнения.

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

 

Синтаксис знака доллара

$( command )

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

 

Пример 1: подстановка команд с использованием синтаксиса знака доллара для проверки строк в файле

Большинство сред Linux с такими командами Coreutils, как cat и shuf, также оснащены командой wc, которая позволяет вам подсчитывать байты, слова и строки в файле. Здесь мы будем использовать его, чтобы просто проверить, содержит ли файл больше определенного количества строк, а затем что-нибудь предпринять.

test ! $( seq 101 | wc -l ) -gt 100 || {
echo do something
}

Примечание

Выражение $( seq 101 | wc -l ) оценивается как целое число 101. В результате выражение test принимает вид test! 101 -gt 100. Кроме того, мы можем вывезти! оператор конвейера и вычисление оставшегося тестового выражения. То есть. Надеюсь, вы согласитесь, что test 101 -gt 100 действительно верен. Затем мы остались с! true в левой части оператора списка ||. ! истина становится ложью; и ложь || становится истинным &&.

 

Синтаксис обратной кавычки

`command`

 

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

 

Пример 2: подстановка команды с использованием синтаксиса обратной кавычки для встраивания вывода вложенной команды в команду echo

Давайте упростим и выведем сообщение с вашим именем пользователя.

echo my username is `whoami`

Примечание

Если ваше имя пользователя «andreyex», приведенная выше команда оценивается как «my username is andreyex».

Теперь, когда вы знаете, как использовать подстановку команд, давайте рассмотрим способы ее использования.

 

Развлечение с заданиями и подстановкой команд

Часто мы хотим присвоить переменной результат выполнения команды. Это можно сделать с помощью подстановки команд.

variable=$( command args... )

 

Например, при сопоставлении с шаблоном bash мы присвоили переменной подчиненные буквы алфавита следующим образом.

Команды

subject=$( echo {z..a} | tr -d ' '  )
echo ${subject}

Вывод

zyxwvutsrqponmlkjihgfedcba

Удобный! Разве вы не рады, что сейчас произошла подмена команды!

 

Развлечения с функциями и подстановкой команд

Давайте свернем нашу собственную функцию карты, которая подсчитывает количество слов, содержащих букву a.

Во-первых, нам нужна функция, которая проверяет, содержит ли какое-то слово букву a. В следующем фрагменте мы будем использовать замену шаблона с помощью расширения параметра и целочисленного атрибута в назначении.

Команды

has_a() {
local instr="${1}"
local -i match=$( test ! "${instr//a}" != "${instr}" || echo 1 )
echo ${match}
}

Если результат замены a из входной строки не является самим собой до замены, мы говорим, что входная строка содержит букву a. В этом случае мы повторяем 1. Результирующая подстановка команды затем подлежит присвоению с целочисленным атрибутом. В случае присвоения пустого значения присвоенное значение принимается равным 0. То есть функция has_a возвращает 0 или 1 в зависимости от наличия буквы a во входной строке.

Вот краткий обзор нашей функции has_a в действии.

Команды

has_a asdf
has_a sdf
has_a df
has_a f
has_a a

 

Вывод

1
0
0
0
1

 

Затем нам нужна функция для циклического перебора слов в предложении с применением функции has_a, которую мы просто назовем map.

Команды

map() {
test ! ${#} -eq 1 || { true ; return ; }
local function_name="${1}"
local first=${2}
local rest=${@:3}
echo "$( ${function_name} ${first} ) $( map ${function_name} ${rest} )"
}

Вот краткий обзор нашей функции карты в действии.

Команды

map has_a a b c
map has_a {a..z}{a..z}
map has_a {a..b}{a..b}{a..b}

Вывод

1 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0

Теперь вы в матрице!

Все, что нам нужно сделать сейчас, это подсчитать единицы, которые мы назовем суммой.

sum() {
test ! ${#} -eq 1 || { echo 0 ; return ; }
local -i first="${1}"
local rest=$( sum ${@:2} )
first+=rest
echo ${first}
}

Это должно сработать!

Вот краткий обзор нашей функции суммы в действии.

Команды

sum $( map has_a {a..b}{a..b}{a..b} )
sum $( map has_a {a..z}{a..z} )
sum $( map has_a {a..c}{a..c} )

Вывод

7
51
5

Больше удовольствия с заданиями: функция настройки

Пока вы здесь, давайте еще немного повеселимся с присваиваниями, исследуя то, что я люблю называть функциями настройки, т.е. мы собираемся создать специализированную функцию для присвоения значения переменной. Как вы уже знаете, нам может потребоваться подстановка команд. Вот как:

Команды

variable() {
echo 1
}
setup-variable() {
variable=$( variable )
}
setup() {
setup-variable
}
main() {
local variable=0
setup
echo ${variable}
}
main
echo ${variable:-empty}

Вывод

1
empty

Упражнения

  1. Перепишите команду из примера 1 без использования оператора конвейера!
  2. Перепишите команду из примера 2, используя синтаксис знака доллара.
  3. Напишите функцию для подсчета слов без использования sum, map и has_a
  4. Напишите «Он / она любит меня», а не программировать этот цикл навсегда
  5. Напишите строку, присваивающую переменной значение второй строки и третьего столбца файла CSV
  6. Напишите строку, назначающую переменной согласие скрипта (Подсказка: используйте xxd)

 

TL; DR;

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

Exit mobile version