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