Если нужно выполнить float выражения, можно использовать сторонние утилиты. Как один из вариантов, сделать функцию fp с таким содержанием:
function fp { # fp - реализация операций с плавающей точкой через awk # usage: fp "выражение" local args="${*:-}" awk "BEGIN { print $args }"}
Арифметика в двойных круглых скобках (( ))
Это best practices для арифметики в bash I think
В двойных круглых скобках (( )) выполняются арифметические вычисления. Внутри (( ))не требуются$ перед именами переменных. Их можно встретить в цикле for или в if:
for ((i=0; i<size; i++)); do :; doneif (( max - 3 > x * 4 )); then :; fi
Результат выражения можно присвоить переменной, добавив $:
max="$(( intro + body + outro - 1 ))"median_loc=$((len / 2))
В операторе if $ не нужен, т.к. там для принятия решения достаточно булевых значений. Если при вычислении выражения в двойных круглых скобках (без $) получается ненулевой результат→ возвращается статус 0 (true), иначе - статус 1 (false). (( )) без $ интерпретируются как выполнение одной/нескольких команд, которые не возвращают результат вычислений. Хоть и есть исключения:
# Bash поддерживает некоторые C-like операторы присваивания(( step ++ ))(( median_loc = len / 2 ))(( dist *= 4 ))
Выражения выше всё равно не возвращают ничего (кроме кода возврата в $?), а только присваивают значение переменным. Их можно оформить и так:
Не юзай "$((step++))" как самостоятельную инструкцию в отдельной строке
Такие выражения опасно юзать как самостоятельные инструкции, ибо они будут возвращать числа (из-за $), которые интерпретатор воспримет как имя какой-то команды: если, например, выражение вернет 3 → оболочка попытается запустить команду с именем 3.
Однако внутри круглых скобок пробелы допускаются, ибо круглые скобки определяют границы этого “слова”.
Пару слов о let
Раньше вместо (( )) использовали (и используют) встроенную команду let:
# Эквивалентные выражения(( step ++ ))let "step++"(( median_loc = len / 2 ))let "median_loc = len / 2"(( dist *= 4 ))let "median_loc = len / 2"
Выражение let бери в кавычки
let принимает только одно “слово”, а пробелы в выражении разделяют выражение на несколько слов (чревато синтаксической ошибкой), и чтобы не было ошибок → арифметическое выражение заключай в кавычки.
”Голая” арифметика
Есть один не очень желательный способ выполнения арифметических вычислений без использования (( )) или let→ суть в объявлении заранее переменной как integer, после которого можно будет с переменной выполнять арифметические вычисления без (( )) или let:
declare -i SEEX=9Y=3SEE=X+Y # 12 (интерпретируется как АРИФМЕТИЧЕСКАЯ операция)SAW=X+Y # X+Y (интерпретируется как СТРОКОВЫЙ литерал)SUU=$X+$Y # 9+3 (интерпретируется как КОНКАТЕНАЦИЯ строк)
Такой стиль выполнения арифметических действий чреват ошибками, ибо:
Можно просто забыть объявить переменную как целочисленную
Оболочка не сообщит об “ошибке”
Не очень очевидно в коде будет, какая из переменных integer
Соус: Книга Идиомы Bash→ Глава 5. Выражения и арифметика