8.1. Операторы | Популярный Linux

Опубликовано Bash в Ср, 23/12/2009 — 20:56

присваивание

variable
assignment

Инициализация переменной или изменение ее значения

=

Универсальный оператор присваивания, пригоден как для сравнения целых чисел, так и для сравнения строк.

  1. var=27
  2. category=minerals  # Пробелы до и после оператора «=» — недопустимы.
Caution

Пусть вас не смущает, что оператор присваивания («=»), по своему внешнему виду, совпадает с оператором сравнения (=).

  1. #    Здесь знак «=»  выступает в качестве оператора сравнения
  2. if [ «$string1« = «$string2« ]
  3. # if [ «X$string1» = «X$string2» ] более отказоустойчивый вариант,
  4. # предохраняет от «сваливания» по ошибке в случае, когда одна из переменных пуста.
  5. # (добавленные символы «X» компенсируют друг друга.)
  6. then
  7.    command
  8. fi

арифметические операторы

+

сложение

вычитание

*

умножение

/

деление

**

возведение в степень

  1. # В Bash, начиная с версии 2.02, был введен оператор возведения в степень — «**».
  2. let «z=5**3»
  3. echo «z = $z«   # z = 125
%

модуль (деление по модулю), возвращает остаток от деления

  1. bash$ echo `expr 5 % 3`
  2. 2
  3.        

Этот оператор может применяться в алгоритмах генерации псевдослучайных чисел в заданном диапазоне (см. Пример 9-23 и Пример 9-26), для форматирования вывода на экран (см. Пример 25-15 и Пример A-7), и даже для генерации простых чисел (см. Пример A-18). На удивление часто операцию деления по модулю можно встретить в различных численных алгоритмах.

Пример 8-1. Наибольший общий делитель

  1. #!/bin/bash
  2. # gcd.sh: поиск наибольшего общего делителя
  3. #         по алгоритму Эвклида
  4. #  Под «наибольшим общим делителем» (нод) двух целых чисел
  5. #+ понимается наибольшее целое число, которое делит оба делимых без остатка.
  6. #  Алгоритм Эвклида выполняет последовательное деление.
  7. #  В каждом цикле,
  8. #+ делимое  <—  делитель
  9. #+ делитель <—  остаток
  10. #+ до тех пор, пока остаток не станет равным нулю (остаток = 0).
  11. #+ The gcd = dividend, on the final pass.
  12. #
  13. #  Замечательное описание алгоритма Эвклида можно найти
  14. #  на сайте Jim Loy, <a href=»http://www.jimloy.com/number/euclids.htm.
  15. #» title=»http://www.jimloy.com/number/euclids.htm.
  16. #»>http://www.jimloy.com/number/euclids.htm.
  17. #</a> ——————————————————
  18. # Проверка входных параметров
  19. ARGS=2
  20. E_BADARGS=65
  21. if [ $# -ne «$ARGS« ]
  22. then
  23.   echo «Порядок использования: `basename $0` первое-число второе-число»
  24.   exit $E_BADARGS
  25. fi
  26. # ——————————————————
  27. gcd ()
  28. {
  29.                                  #  Начальное присваивание.
  30.   dividend=$1                    #  В сущности, не имеет значения
  31.   divisor=$2                     #+ какой из них больше.
  32.                                  #  Почему?
  33.   remainder=1                    #  Если переменные неинициализировать,
  34.                                  #+ то работа сценария будет прервана по ошибке
  35.                                  #+ в первом же цикле.
  36.   until [ «$remainder« -eq 0 ]
  37.   do
  38.     let «remainder = $dividend % $divisor«
  39.     dividend=$divisor            # Повторить цикл с новыми исходными данными
  40.     divisor=$remainder
  41.   done                           # алгоритм Эвклида
  42. }                                # последнее $dividend и есть нод.
  43. gcd $1 $2
  44. echo; echo «НОД чисел $1 и $2 = $dividend«; echo
  45. # Упражнение :
  46. # ———
  47. #  Вставьте дополнительную проверку входных аргументов,
  48. #+ и предусмотрите завершение работы сценария с сообщением об ошибке, если
  49. #+ входные аргументы не являются целыми числами.
  50. exit 0
+=

«плюс-равно» (увеличивает значение переменной на заданное число)

let "var += 5" значение переменной var будет увеличено на 5.

-=

«минус-равно» (уменьшение значения переменной на заданное число)

*=

«умножить-равно» (умножить значение переменной на заданное число, результат записать в переменную)

let "var *= 4" значение переменной var будет увеличено в 4 раза.

/=

«слэш-равно» (уменьшение значения переменной в заданное число раз)

%=

«процент-равно» (найти остаток от деления значения переменной на заданное число, результат записать в переменную)

Арифметические операторы очень часто используются совместно с командами expr и let.

Пример 8-2. Арифметические операции

  1. #!/bin/bash
  2. # От 1 до 6 пятью различными способами.
  3. n=1; echo -n «$n «
  4. let «n = $n + 1″   # let «n = n + 1»   тоже допустимо
  5. echo -n «$n «
  6. : $((n = $n + 1))
  7. # оператор «:» обязателен, поскольку в противном случае, Bash будет
  8. #+ интерпретировать выражение «$((n = $n + 1))» как команду.
  9. echo -n «$n «
  10. n=$(($n + 1))
  11. echo -n «$n «
  12. : $[ n = $n + 1 ]
  13. # оператор «:» обязателен, поскольку в противном случае, Bash будет
  14. #+ интерпретировать выражение «$[ n = $n + 1 ]» как команду.
  15. # Не вызывает ошибки даже если «n» содержит строку.
  16. echo -n «$n «
  17. n=$[ $n + 1 ]
  18. #  Не вызывает ошибки даже если «n» содержит строку.
  19. #* Старайтесь избегать употребления такой конструкции,
  20. #+ поскольку она уже давно устарела и не переносима.
  21. echo -n «$n «; echo
  22. # Спасибо Stephane Chazelas.
  23. exit 0
Note

Целые числа в Bash фактически являются длинными целыми (32-бит) со знаком, с диапазоном изменений от -2147483648 до 2147483647. Если в результате какой либо операции эти пределы будут превышены, то результат получится ошибочным.

  1. a=2147483646
  2. echo «a = $a«      # a = 2147483646
  3. let «a+=1»         # Увеличить «a» на 1.
  4. echo «a = $a«      # a = 2147483647
  5. let «a+=1»         # увеличить «a» еще раз, с выходом за границы диапазона.
  6. echo «a = $a«      # a = -2147483648
  7.                    #      ОШИБКА! (выход за границы диапазона)

Версия Bash 2.05b, поддерживает 64-ьитные целые числа.

Caution

Bash ничего не знает о существовании чисел с плавающей запятой. Такие числа, из-за наличия символа десятичной точки, он воспринимает как строки.

  1. a=1.5
  2. let «b = $a + 1.3″  # Ошибка.
  3. # t2.sh: let: b = 1.5 + 1.3: syntax error in expression (error token is «.5 + 1.3»)
  4. echo «b = $b«       # b=1

Для работы с числами с плавающей запятой в сценариях можно
использовать утилиту-калькулятор bc.

битовые операции. Битовые операции очень редко используются в сценариях командного интерпретатора. Их главное назначение, на мой взгляд, установка и проверка некоторых значений, читаемых из портов ввода-вывода и сокетов. «Битовые операции» гораздо более уместны в компилирующих языках программирования, таких как C и C++.

битовые операции

<<

сдвигает на 1 бит влево (умножение на 2)

<<=

«сдвиг-влево-равно»

let "var <<= 2" значение переменной var сдвигается влево на 2 бита (умножается на 4)

>>

сдвиг вправо на 1 бит (деление на 2)

>>=

«сдвиг-вправо-равно» (имеет смысл обратный <<=)

&

по-битовое И (AND)

&=

«по-битовое И-равно»

|

по-битовое ИЛИ (OR)

|=

«по-битовое ИЛИ-равно»

~

по-битовая инверсия

!

По-битовое отрицание

^

по-битовое ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR)

^=

«по-битовое ИСКЛЮЧАЮЩЕЕ-ИЛИ-равно»

логические операции

&&

логическое И (and)

  1. if [ $condition1 ] && [ $condition2 ]
  2. # То же самое, что:  if [ $condition1 -a $condition2 ]
  3. # Возвращает true если оба операнда condition1 и condition2 истинны…
  4. if [[ $condition1 && $condition2 ]]    # То же верно
  5. # Обратите внимание: оператор && не должен использоваться внутри [ … ].
Note

оператор &&, в зависимости от контекста, может так же использоваться в И-списках для построения составных команд.

||

логическое ИЛИ (or)

  1. if [ $condition1 ] || [ $condition2 ]
  2. # То же самое, что:  if [ $condition1 -o $condition2 ]
  3. # Возвращает true если хотя бы один из операндов истинен…
  4. if [[ $condition1 || $condition2 ]]    # Also works.
  5. # Обратите внимание: оператор || не должен использоваться внутри [ … ].
Note

Bash производит проверку кода возврата КАЖДОГО из операндов в логических выражениях.

Пример 8-3. Построение сложных условий, использующих && и ||

  1. #!/bin/bash
  2. a=24
  3. b=47
  4. if [ «$a« -eq 24 ] && [ «$b« -eq 47 ]
  5. then
  6.   echo «Первая проверка прошла успешно.»
  7. else
  8.   echo «Первая проверка не прошла.»
  9. fi
  10. # ОКА:  if [ «$a» -eq 24 && «$b» -eq 47 ]
  11. #          пытается выполнить  ‘ [ «$a» -eq 24 ‘
  12. #          и терпит неудачу наткнувшись на ‘]’.
  13. #
  14. #    if [[ $a -eq 24 && $b -eq 24 ]]   это правильный вариант
  15. #    (в строке 17 оператор «&&» имеет иной смысл, нежели в строке 6.)
  16. #    Спасибо Stephane Chazelas.
  17. if [ «$a« -eq 98 ] || [ «$b« -eq 47 ]
  18. then
  19.   echo «Вторая проверка прошла успешно.»
  20. else
  21.   echo «Вторая проверка не прошла.»
  22. fi
  23. #  Опции -a и -o предоставляют
  24. #+ альтернативный механизм проверки условий.
  25. #  Спасибо Patrick Callahan.
  26. if [ «$a« -eq 24 -a «$b« -eq 47 ]
  27. then
  28.   echo «Третья проверка прошла успешно.»
  29. else
  30.   echo «Третья проверка не прошла.»
  31. fi
  32. if [ «$a« -eq 98 -o «$b« -eq 47 ]
  33. then
  34.   echo «Четвертая проверка прошла успешно.»
  35. else
  36.   echo «Четвертая проверка не прошла.»
  37. fi
  38. a=rhino
  39. b=crocodile
  40. if [ «$a« = rhino ] && [ «$b« = crocodile ]
  41. then
  42.   echo «Пятая проверка прошла успешно.»
  43. else
  44.   echo «Пятая проверка не прошла.»
  45. fi
  46. exit 0

Операторы && и || могут использоваться и в арифметических вычислениях.

  1. bash$ echo $(( 1 && 2 )) $((3 && 0)) $((4 || 0)) $((0 || 0))
  2. 1 0 1 0
  3.        

прочие операции

,

запятая

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

  1. let «t1 = ((5 + 3, 7 — 1, 15 — 4))»
  2. echo «t1 = $t1«               # t1 = 11
  3. let «t2 = ((a = 9, 15 / 3))»  #  Выполняется присваивание «a» = 9,
  4.                               #+ а затем вычисляется «t2».
  5. echo «t2 = $t2    a = $a«     # t2 = 5    a = 9

Оператор запятая чаще всего находит применение в циклах for. См. Пример 10-12.

Запись опубликована в рубрике Без рубрики. Добавьте в закладки постоянную ссылку.