Объединение выражений

We use cookies. Read the Privacy and Cookie Policy

Для более сложных вычислений существует возможность объединения выражений. Объединяются выражения с помощью логических операторов. Мы уже встречались с ними в главе 17, когда изучали команду find. Всего команды test и [[ ]] поддерживают три логические операции. Это И (AND), ИЛИ (OR) и НЕ (NOT). Для представления этих операций test и [[ ]] используют разные операторы, как показано в табл. 27.4.

Таблица 27.4. Логические операторы

Операция

test

[[ ]] и (( ))

И

-a

&&

ИЛИ

-o

||

НЕ

!

!

Ниже приводится пример использования операции И (AND). Следующий сценарий определяет вхождение целочисленного значения в определенный диапазон:

#!/bin/bash

# test-integer3: проверка вхождения целочисленного значения

# в определенный диапазон.

MIN_VAL=1

MAX_VAL=100

INT=50

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then

if [[ INT -ge MIN_VAL && INT -le MAX_VAL ]]; then

echo "$INT is within $MIN_VAL to $MAX_VAL."

else

echo "$INT is out of range."

fi

else

echo "INT is not an integer." >&2

exit 1

fi

Этот сценарий определяет, попадает ли целочисленное значение INT в диапазон между MIN_VAL и MAX_VAL. Эта операция выполняется единственной командой [[ ]], включающей два выражения, разделенных оператором &&. Ту же проверку можно выполнить с помощью test:

if [ $INT -ge $MIN_VAL -a $INT -le $MAX_VAL ]; then

echo "$INT is within $MIN_VAL to $MAX_VAL."

else

echo "$INT is out of range."

fi

Оператор отрицания! обращает результат выражения. Он возвращает истинное значение, если выражение ложно, и ложное значение, если выражение истинно. В следующем сценарии мы изменили логику вычислений, чтобы определить, находится ли значение INT за пределами указанного диапазона:

#!/bin/bash

# test-integer4: проверка выхода целочисленного значения

# за границы определенного диапазона.

MIN_VAL=1

MAX_VAL=100

INT=50

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then

if [[ ! (INT -ge MIN_VAL && INT -le MAX_VAL) ]]; then

echo "$INT is outside $MIN_VAL to $MAX_VAL."

else

echo "$INT is in range."

fi

else

echo "INT is not an integer." >&2

exit 1

fi

Здесь выражение заключено в круглые скобки для группировки. Если этого не сделать, оператор отрицания будет применяться к результату первого выражения, а не к объединению двух выражений. Ту же проверку можно реализовать с помощью test:

if [ ! ( $INT -ge $MIN_VAL -a $INT -le $MAX_VAL ) ]; then

echo "$INT is outside $MIN_VAL to $MAX_VAL."

else

echo "$INT is in range."

fi

Поскольку все выражения и операторы в команде test интерпретируются командной оболочкой как аргументы (в отличие от [[ ]] и (( ))), символы, имеющие специальное значение для bash, такие как <, >, ( и ), необходимо заключать в кавычки или экранировать.

Учитывая, что команды test и [[ ]] до определенной степени равноценны, возникает вопрос: какой из них отдать предпочтение? Команда test является традиционной (и частью стандарта POSIX), тогда как команда [[ ]] характерна для bash. Уметь пользоваться командой test крайне важно, потому что она применяется очень широко, но команда [[ ]] проще и удобнее в использовании.

Переносимость — беспочвенные страхи от непонимания

Если вам доведется побеседовать с «истинными» пользователями Unix, вы быстро обнаружите, что многие из них Linux терпеть не могут. Они оценивают его как нечто нечистое и греховное. Один из принципов таких ревнителей Unix — все должно быть переносимым. То есть любой сценарий, написанный вами, должен работать без изменений в любой Unix-подобной системе.

Пользователи Unix имеют веские основания рассчитывать на это. Наблюдая последствия для мира Unix, вызванные внедрением проприетарных расширений команд и командных оболочек до появления POSIX, они естественно опасаются влияния Linux на их любимую ОС.

Но переносимость имеет серьезный недостаток. Она тормозит прогресс и требует приведения всего и вся к «наименьшему общему знаменателю». Для сценариев на языке командной оболочки это означает, что они должны быть совместимы с sh, оригинальной командной оболочкой Bourne.

Этот недостаток служит отговоркой, которой пользуются производители проприетарных расширений для их оправдания, только они называют их «новшествами». Но в действительности они замыкают пользователей на себя.

Инструменты GNU, такие как bash, не имеют подобных ограничений. Они способствуют переносимости благодаря поддержке стандартов и всеобщей доступности. bash и другие инструменты GNU можно установить практически в любую систему, даже в Windows, совершенно бесплатно. Поэтому не бойтесь использовать все возможности, имеющиеся в командной оболочке bash. Она действительно переносима.