Подстановки арифметических выражении Linux

Подстановки вывода команд и параметров являются для программирования на языке командного интерпретатора практически самыми важными конструкциями.

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

Нужно отметить, что аргументы команды еexpr отделяются пробелами, как и у любой другой команды, например ls.

Запуск внешних команд влечет за собой накладные расходы в виде системных вывозов fork и execve, поэтому во многих диалектах языка командного интерпретатора реализованы аналогичная встроенная команда арифметических вычислений let и арифметическая подстановка в виде стандартной POSIX-конструкции $((expression)), а в некоторых еще и в нестандартном виде $[expression].

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

Арифметические действия командного интерпретатора

bender@ubuntu: ~$ CIRCLE=’expr 2 * $RADIUS * 355 / 113′

bender@ubuntu:~$ let CIRCLE=2*RADIUS*355/113

bender@ubuntu:~$ CIRCLE=$((2 * RADIUS * 355/113))

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

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

Библиотеки больше 10 Мбайт

bender@ubuntu:~$ set -x

bender@ubuntu:~$ find /lib /usr/lib -name ‘*.so.*’ -size +$((1024*1024*10))c

+ find /lib /usr/lib -name ‘*.so.*’ -size +10485760C

/usr/lib/libicudata. so. 48.1.1

/usr/lib/libwireshark.so.1.1.7

/usr/lib/i386-linux-gnu/libQtGui.so.4.8.1

/usr/lib/libwebkitgtk-1.0.so.0.13.4

Пример из листинга ниже содержит две вложенные друг в друга подстановки — подстановку вывода команды date в арифметическую подстановку.

Команда find при поиске модифицированных (-mtine, modification time) файлов использует единицы измерения «дней назад», и при поиске файлов в каталоге /var/lib/dpkg/info (это база данных пакетного менеджера dpkg(1) об установленных в систему пакетах программного обеспечения), изменившихся в период с 20.12.2018 по. 25.12.2018 приходится рассчитывать количество «дней назад» до этих дат.

Для расчета используются команда date и W:[UNIX-время], вычисляющая как целое количество секунд, прошедших от 01.01.1970 00:00 UTC до нужного момента, и арифметическая подстановка, вычисляющая количество «дней назад».

Сначала вычисляется количество «секунд назад» как разница между текущим UNIX-временем и UNIX-временем указанной даты, после чего вычисляется количество «дней назад» путем деления на 60 секунд в минуте, 60 минут в часе и 24 часа в дне. При помощи команды stat подтверждается правильность поиска путем анализа даты модификации найденных файлов.

Пакеты программного обеспечения, установленные в определенный период

bender@ubuntu:~$ set -x

bender@ubuntu:~$ find /var/lib/dpkg/info -name ‘ *.list’ \ ↵

> -mtime -$[ ($(date+%s — $(date-d 2018-12-26 +%s))/ (24*66*60) ] \ ↵

> -mtim -$[ ($(date+%s — $(date-d 2018-12-20 +%s)) / (24*60*60) ] | ↵

> xargs stat -c %y:%n

+ xargs stat -c %y:%n

++ date +%s

++ date -d 2018-12-25 +%s ++ date +%s

++ date -d 2018-12-20 +%s

+ find /var/lib/dpkg/info -name ‘*.list’ -mtine +1  -mtime -6 »

2018-12-24 15:59:50.697681116 +0300: /var/lib/dpkg/info/flex. list

2018-12-20 18:02:51.656846947 +0300:/var/lib/dpkg/info/bison. list

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

В этом случае командный интерпретатор каждую последующую экранную строку предваряет «вторичным» приглашением PS2, а не «первичным» приглашением PS1. Символ перевода строки после символа конвейера | экранирования не требует, т. к. командному интерпретатору очевидна необходимость ввода второй команды конвейера.

Добавить комментарий