Рейтинг
0.00
голосов:
0
avatar

Программирование на языке сценариев  

Операторы

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

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

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

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

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

# Здесь знак "=" выступает в качестве оператора сравнения

if [ "$string1" = "$string2" ]
# if [ «X$string1» = «X$string2» ] более отказоустойчивый вариант,
# предохраняет от «сваливания» по ошибке в случае, когда одна из переменных пуста.
# (добавленные символы «X» компенсируют друг друга.)
then
command
fi

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

+
сложение

— вычитание

*
умножение

/
деление

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

# В Bash, начиная с версии 2.02, был введен оператор возведения в степень — "**".

let «z=5**3»
echo «z = $z» # z = 125

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

bash$ echo `expr 5 % 3`
2

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

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

#!/bin/bash
# gcd.sh: поиск наибольшего общего делителя
# по алгоритму Эвклида

# Под «наибольшим общим делителем» (нод) двух целых чисел
#+ понимается наибольшее целое число, которое делит оба делимых без остатка.

# Алгоритм Эвклида выполняет последовательное деление.
# В каждом цикле,
#+ делимое < — делитель
#+ делитель < — остаток
#+ до тех пор, пока остаток не станет равным нулю (остаток = 0).
#+ The gcd = dividend, on the final pass.
#
# Замечательное описание алгоритма Эвклида можно найти
# на сайте Jim Loy, www.jimloy.com/number/euclids.htm.

# — # Проверка входных параметров
ARGS=2
E_BADARGS=65

if [ $# -ne "$ARGS" ]
then
echo «Порядок использования: `basename $0` первое-число второе-число»
exit $E_BADARGS
fi
# — gcd ()
{

# Начальное присваивание.
dividend=$1 # В сущности, не имеет значения
divisor=$2 #+ какой из них больше.
# Почему?

remainder=1 # Если переменные неинициализировать,
#+ то работа сценария будет прервана по ошибке
#+ в первом же цикле.

until [ "$remainder" -eq 0 ]
do
let «remainder = $dividend % $divisor»
dividend=$divisor # Повторить цикл с новыми исходными данными
divisor=$remainder
done # алгоритм Эвклида

} # последнее $dividend и есть нод.

gcd $1 $2

echo; echo «НОД чисел $1 и $2 = $dividend»; echo

# Упражнение:
# — # Вставьте дополнительную проверку входных аргументов,
#+ и предусмотрите завершение работы сценария с сообщением об ошибке, если
#+ входные аргументы не являются целыми числами.

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

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

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

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

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

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

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

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

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

#!/bin/bash
# От 1 до 6 пятью различными способами.

n=1; echo -n "$n "

let «n = $n + 1» # let «n = n + 1» тоже допустимо
echo -n "$n "

: $((n = $n + 1))
# оператор ":" обязателен, поскольку в противном случае, Bash будет
#+ интерпретировать выражение "$((n = $n + 1))" как команду.
echo -n "$n "

n=$(($n + 1))
echo -n "$n "

: $[ n = $n + 1 ]
# оператор ":" обязателен, поскольку в противном случае, Bash будет
#+ интерпретировать выражение "$[ n = $n + 1 ]" как команду.
# Не вызывает ошибки даже если «n» содержит строку.
echo -n "$n "

n=$[ $n + 1 ]
# Не вызывает ошибки даже если «n» содержит строку.
#* Старайтесь избегать употребления такой конструкции,
#+ поскольку она уже давно устарела и не переносима.
echo -n "$n "; echo

# Спасибо Stephane Chazelas.

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

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

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

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

a=1.5

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

echo «b = $b» # b=1
Для работы с числами с плавающей запятой в сценариях можно использовать утилиту-калькулятор bc.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

if [ $condition1 ] && [ $condition2 ]
# То же самое, что: if [ $condition1 -a $condition2 ]
# Возвращает true если оба операнда condition1 и condition2 истинны…

if [[ $condition1 && $condition2 ]] # То же верно
# Обратите внимание: оператор && не должен использоваться внутри [… ].

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

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

if [ $condition1 ] || [ $condition2 ]
# То же самое, что: if [ $condition1 -o $condition2 ]
# Возвращает true если хотя бы один из операндов истинен…

if [[ $condition1 || $condition2 ]] # Also works.
# Обратите внимание: оператор || не должен использоваться внутри [… ].

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

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

#!/bin/bash

a=24
b=47

if [ "$a" -eq 24 ] && [ "$b" -eq 47 ]
then
echo «Первая проверка прошла успешно.»
else
echo «Первая проверка не прошла.»
fi

# ОКА: if [ "$a" -eq 24 && "$b" -eq 47 ]
# пытается выполнить ' [ "$a" -eq 24 '
# и терпит неудачу наткнувшись на ']'.
#
# if [[ $a -eq 24 && $b -eq 24 ]] это правильный вариант
# (в строке 17 оператор "&&" имеет иной смысл, нежели в строке 6.)
# Спасибо Stephane Chazelas.

if [ "$a" -eq 98 ] || [ "$b" -eq 47 ]
then
echo «Вторая проверка прошла успешно.»
else
echo «Вторая проверка не прошла.»
fi

# Опции -a и -o предоставляют
#+ альтернативный механизм проверки условий.
# Спасибо Patrick Callahan.

if [ "$a" -eq 24 -a "$b" -eq 47 ]
then
echo «Третья проверка прошла успешно.»
else
echo «Третья проверка не прошла.»
fi

if [ "$a" -eq 98 -o "$b" -eq 47 ]
then
echo «Четвертая проверка прошла успешно.»
else
echo «Четвертая проверка не прошла.»
fi

a=rhino
b=crocodile
if [ "$a" = rhino ] && [ "$b" = crocodile ]
then
echo «Пятая проверка прошла успешно.»
else
echo «Пятая проверка не прошла.»
fi

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

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

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

,
запятая

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

let «t1 = ((5 + 3, 7 — 1, 15 — 4))»
echo «t1 = $t1» # t1 = 11

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

Вложенные условные операторы if/then

Операторы проверки условий if/then могут быть вложенными друг в друга. Конечный результат будет таким же как если бы результаты всех проверок были объединены оператором &&.

if [ condition1 ]
then
if [ condition2 ]
then
do-something # Только если оба условия «condition1» и «condition2» истинны.
fi
fi

Операции сравнения

сравнение целых чисел

-eq

равно

if [ "$a" -eq "$b" ]

-ne
не равно

if [ "$a" -ne "$b" ]

-gt
больше

if [ "$a" -gt "$b" ]

-ge
больше или равно

if [ "$a" -ge "$b" ]


( Читать дальше )

Операции проверки файлов

Возвращает true если…

-e
файл существует

-f
обычный файл (не каталог и не файл устройства)

-s
ненулевой размер файла

-d
файл является каталогом

-b
файл является блочным устройством (floppy, cdrom и т.п.)

-c
файл является символьным устройством (клавиатура, модем, звуковая карта и т.п.)

-p
файл является каналом

-h
файл является символической ссылкой

-L
файл является символической ссылкой

-S

( Читать дальше )

Конструкции проверки условий

практически любой язык программирования включает в себя условные операторы, предназначенные для проверки условий, чтобы выбрать тот или иной путь развития событий в зависимости от этих условий. В Bash, для проверки условий, имеется команда test, различного вида скобочные операторы и условный оператор if/then.

Оператор if/then проверяет — является ли код завершения списка команд 0 (поскольку 0 означает «успех»), и если это так, то выполняет одну, или более, команд, следующие за словом then.


( Читать дальше )

Завершение и код завершения

… эта часть Bourne shell покрыта мраком, тем не менее все пользуются ею.

Chet Ramey
Команда exit может использоваться для завершения работы сценария, точно так же как и в программах на языке C. Кроме того, она может возвращать некоторое значение, которое может быть проанализировано вызывающим процессом.


( Читать дальше )

Кавычки

Кавычки, ограничивающие строки с обеих сторон, служат для предотвращения интерпретации специальных символов, которые могут находиться в строке. (Символ называется «специальным», если он несет дополнительную смысловую нагрузку, например символ шаблона — *.)

bash$ ls -l [Vv]*
-rw-rw-r-- 1 bozo bozo 324 Apr 2 15:05 VIEWDATA.BAT
-rw-rw-r-- 1 bozo bozo 507 May 4 14:25 vartrace.sh
-rw-rw-r-- 1 bozo bozo 539 Apr 14 17:11 viewdata.sh

bash$ ls -l '[Vv]*'
ls: [Vv]*: No such file or directory


( Читать дальше )

Специальные типы переменных

локальные переменные
переменные, область видимости которых ограничена блоком кода или телом функции (см так же локальные переменные в функциях)

переменные окружения
переменные, которые затрагивают командную оболочку и порядок взаимодействия с пользователем

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


( Читать дальше )

Переменные Bash не имеют типа

В отличие от большинства других языков программирования, Bash не производит разделения переменных по «типам». По сути, переменные Bash являются строковыми переменными, но, в зависимости от контекста, Bash допускает целочисленную арифметику с переменными. Определяющим фактором здесь служит содержимое переменных.

Пример 4-4. Целое число или строка?

#!/bin/bash
# int-or-string.sh: Целое число или строка?


( Читать дальше )

Присваивание значений переменным

=
оператор присваивания (пробельные символы до и после оператора — недопустимы)

Не путайте с операторами сравнения = и -eq!

Обратите внимание: символ = может использоваться как в качестве оператора присваивания, так и в качестве оператора сравнения, конкретная интерпретация зависит от контекста применения.

Пример 4-2. Простое присваивание

#!/bin/bash
# Явные переменные


( Читать дальше )