N_RESULTS=$( echo "($DECI - 1) / 10 + 1" | bc -l )
Что let
делает
Рассматривать:
let "N_RESULTS = ($DECI - 1) / 10 + 1" | bc -l
Этот трубопровод состоит из двух частей. Первым является команда let
оболочки. Из-за |
Символ, вывод команды let
передается в стандартный поток команды bc
. Хотя ' let
способен выполнять целочисленную арифметику и может присваивать значения переменной, он не производит никакого вывода. Следовательно, даже если бы он работал правильно, он ничего не передал бы в bc
.
Вот пример рабочей команды let
:
$ let "result = (123 - 1) / 10 + 1"
$ echo $result
13
Однако, если бы мы предоставили аргумент с плавающей запятой, возникла бы ошибка:
$ let "result = (123.0 - 1) / 10 + 1"
bash: let: result = (123.0 - 1) / 10 + 1: syntax error: invalid arithmetic operator (error token is ".0 - 1) / 10 + 1")
Команда let
, как и остальная часть оболочки, выполняет только целочисленную арифметику.
Что делает bc
bc
выполняет арифметику с плавающей запятой и может использоваться для назначения и управления переменными:
$ echo "result = (123.0123 - 1) / 10 + 1; print result" | bc -l
13.20123000000000000000
Тем не менее, обратите внимание, что вышесказанное само по себе не создает никаких переменных, которые можно использовать в оболочке. Определение result
истекает, когда bc
заканчивает обработку. Чтобы передать значение обратно в оболочку, нам нужно выполнить присвоение переменной оболочки, например:
$ result=$(echo "(123.0123 - 1) / 10 + 1" | bc -l )
$ echo $result
13.20123000000000000000
Конструкция $(...)
называется подстановкой команд. Он запускает команду, в данном случае конвейер echo и bc, и помещает свой стандартный вывод в командную строку, где он назначается переменной result
.
В качестве дополнительного примечания обычно рекомендуется использовать строчные имена для переменных оболочки. Переменные оболочки системы - все в верхнем регистре, и вы не хотите случайно перезаписывать одну из них.
Что такое bc
эквивалент для [[ $offset -lt $result ]]
Команды test
оболочки, включая [
и [[
, создают полезный код завершения, который можно использовать в if
, while
и других контекстах, таких как &&
и ||
где коды выхода используются для определения потока программы. bc
не подражает такому поведению. Он возвращает код выхода 0
для любого успешного расчета. Возвращает ненулевые коды выхода, если произошла ошибка. Приведенные ниже примеры показывают, как с помощью grep
bc
можно использовать для установки полезных кодов выхода.
В GNU bc
реляционные выражения оцениваются в 1
для истины и 0
для ложных. Итак, чтобы проверить, меньше ли offset
чем result
, мы просто проверяем, возвращает ли bc
0
или 1
. Здесь grep
используется для проверки вывода bc
и установить соответствующий код возврата , который может быть использован в if
в while
или в других местах , где оболочка будет проверить код возврата. Например:
$ offset=1.25; result=1.33
$ echo "$offset < $result" | bc -l | grep -q 1 && echo yes || echo no
yes
$ offset=1.35
$ echo "$offset < $result" | bc -l | grep -q 1 && echo yes || echo no
no
Под не GNU bc
можно сделать то же самое, но формально, if
требуется оператор:
echo "if ($offset < $result) print 1 else print 0 " | bc -l | grep -q 1 && echo yes || echo no