Командная строка Linux
Шрифт:
Таблица 34.4. Битовые операторы
Оператор
Описание
~
Поразрядное отрицание. Изменяет значения всех битов в числе на противоположные
<<
Поразрядный сдвиг влево. Сдвигает все биты в числе на один разряд влево
>>
Поразрядный сдвиг вправо. Сдвигает все биты в числе на один разряд вправо
&
Поразрядная операция И (AND). Выполняет операцию И над всеми битами двух чисел
|
Поразрядная операция ИЛИ (OR). Выполняет операцию ИЛИ над всеми битами двух чисел
^
Поразрядная
Обратите внимание, что для всех битовых операторов, кроме поразрядного отрицания, существуют соответствующие операторы присваивания (например, <<=).
Ниже показано, как с использованием оператора поразрядного сдвига влево вывести список степеней 2:
[me@linuxbox ~]$ for ((i=0;i<8;++i)); do echo $((1<<i)); done
1
2
4
8
16
32
64
128
Логические операторы
Как мы узнали в главе 27, составная команда поддерживает разные операторы сравнения. Однако существует еще несколько операторов, которые можно использовать для оценки. Полный список приводится в табл. 34.5.
Таблица 34.5. Операторы сравнения
Оператор
Описание
<=
Меньше или равно
>=
Больше или равно
<
Меньше
>
Больше
==
Равно
!=
Не равно
&&
Логическое И (AND)
||
Логическое ИЛИ (OR)
выражение1?выражение2:выражение3
Тернарный (трехместный) оператор сравнения. Если выражение1 вернет ненулевое значение (арифметическую истину), будет выполнено выражение2, иначе — выражение3
При использовании логических операторов в арифметических выражениях действуют следующие правила: выражение, возвращающее 0, считается ложным, а выражение, возвращающее ненулевое значение, — истинным. Составная команда отображает результаты в обычные для командной оболочки коды завершения:
[me@linuxbox ~]$ if ((1)); then echo "true"; else echo "false"; fi
true
[me@linuxbox ~]$ if ((0)); then echo "true"; else echo "false"; fi
false
Самым странным из логических операторов выглядит тернарный (или трехместный) оператор. Этот оператор (заимствованный из языка программирования C) самостоятельно выполняет логическую проверку. Его можно использовать вместо инструкции if/then/else. Он оперирует тремя арифметическими выражениями (этот оператор не работает со строками), и если первое выражение оценивается как истинное (то есть возвращает ненулевое значение), выполняется второе выражение. Иначе выполняется третье выражение. Опробуем его в командной строке.
[me@linuxbox ~]$ a=0
[me@linuxbox ~]$ ((a<1?++a:--a))
[me@linuxbox ~]$ echo $a
1
[me@linuxbox ~]$ ((a<1?++a:--a))
[me@linuxbox ~]$ echo $a
0
Этот пример реализует переключение значения переменной. Каждый раз, когда выполняется оператор, значение переменной a переключается с 0 на 1 или обратно.
Обратите
[me@linuxbox ~]$ a=0
[me@linuxbox ~]$ ((a<1?a+=1:a-=1))
bash: ((: a<1?a+=1:a-=1: attempted assignment to non-variable (error token is "-=1")
Эту проблему можно решить, заключив выражения присваивания в круглые скобки:
[me@linuxbox ~]$ ((a<1?(a+=1):(a-=1)))
Далее приводится более полный пример использования арифметических операторов в сценарии, который выводит простую таблицу чисел:
#!/bin/bash
# arith-loop: сценарий для демонстрации арифметических операторов
finished=0
a=0
printf "a\ta**2\ta**3\n"
printf "=\t====\t====\n"
until ((finished)); do
b=$((a**2))
c=$((a**3))
printf "%d\t%d\t%d\n" $a $b $c
((a<10?++a:(finished=1)))
done
В этом сценарии мы реализовали цикл until, проверяющий значение переменной finished. Первоначально переменной присвоено значение 0 (арифметическая ложь). Цикл продолжается, пока эта переменная не получит ненулевое значение. Внутри цикла вычисляются квадрат и куб переменной-счетчика a. В конце цикла выполняется проверка значения этой переменной. Если оно меньше 10 (максимальное число итераций), она увеличивается на 1, иначе переменной finished присваивается значение 1, что превращает ее в арифметическую истину, и цикл завершается. Запустив сценарий, вы получите следующий результат:
[me@linuxbox ~]$ arith-loop
a a**2 a**3
= ==== ====
0 0 0
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
bc — язык калькулятора для вычислений с произвольной точностью
Мы уже знаем, что командная оболочка поддерживает все виды арифметических вычислений с целыми числами, но как быть, если понадобится реализовать какие-нибудь вычисления из высшей математики или хотя бы просто задействовать вещественные числа? Ответ: никак. По крайней мере, средствами командной оболочки. Для подобных вычислений придется использовать внешнюю программу. Существует множество вариантов решения этой проблемы. Одно из них — использовать программы на встроенном Perl или AWK, но, к сожалению, описание этих языков выходит далеко за рамки данной книги.
Другое решение — использовать специализированную программу-калькулятор. В большинстве систем Linux имеется одна из таких программ — программа с именем bc.
Программа bc читает файл с исходным кодом на собственном языке, напоминающем язык C, и выполняет его. Сценарий на языке bc можно хранить в отдельном файле или передавать его на стандартный ввод программы. Язык bc поддерживает массу возможностей, включая переменные, циклы и функции, определяемые программистом. Мы не будем рассматривать программу bc во всех подробностях, а познакомимся лишь с некоторыми ее возможностями, чтобы вы могли получить общее представление. Неплохое описание программы bc можно найти на странице справочного руководства (man).