Изменить стиль страницы

3. Если код выхода не равен 0 и существует условие else, оболочка выполняет команды, расположенные после ключевого слова else.

4. Условный оператор заканчивается ключевым словом fi.

11.5.1. Немного о пустом списке параметров

Есть небольшая проблема в условном операторе из предыдущего примера, вызванная весьма распространенной ошибкой: переменная $1 может оказаться пустой, так как пользователь может не ввести параметр. При отсутствии параметра команда тестирования прочитает [ = hi ], и тогда команда [ прервет исполнение, выдав ошибку. Этого можно избежать, если заключить параметр в кавычки одним из приведенных ниже способов (оба являются общепринятыми):

if [ "$1" = hi ]; then

if [ x"$1" = x"hi" ]; then

11.5.2. Использование других команд для проверки условий

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

Существует множество возможностей применять другие команды вместо [. Вот пример, в котором использована команда grep:

#!/bin/sh

if grep -q daemon /etc/passwd; then

    echo The daemon user is in the passwd file.

else

    echo There is a big problem. daemon is not in the passwd file.

fi

11.5.3. Ключевое слово elif

Ключевое слово elif позволяет вам связать вместе условные операторы if, как показано ниже. Однако не слишком увлекайтесь использованием elif, так как конструкция case, о которой вы узнаете в подразделе 11.5.6, часто оказывается более подходящей.

#!/bin/sh

if [ "$1" = "hi" ]; then

   echo 'The first argument was "hi"'

elif [ "$2" = "bye" ]; then

   echo 'The second argument was "bye"'

else

   echo -n 'The first argument was not "hi" and the second was not "bye"— '

   echo They were '"'$1'"' and '"'$2'"'

fi

11.5.4. Логические конструкции && и ||

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

command1 && command2

Здесь оболочка запускает команду command1, и если ее код выхода равен 0, оболочка запускает также и команду command2. Конструкция || подобна первой: если команда, расположенная перед символами ||, возвращает ненулевой код выхода, оболочка запускает вторую команду.

Конструкции && и || часто находят себе применение в проверках if, и в обоих случаях код выхода последней запущенной команды определяет то, как оболочка обработает условный оператор. В случае с конструкцией &&, если первая команда завершается неудачно, оболочка использует ее код выхода для инструкции if, но если первая команда завершена успешно, оболочка применяет для условного оператора код выхода второй команды. В случае с конструкцией || оболочка использует код выхода первой команды при ее успешном выполнении или код выхода второй команды, если первая завершила работу неудачно.

Например:

#!/bin/sh

if [ "$1" = hi ] || [ "$1" = bye ]; then

    echo 'The first argument was "'$1'"'

fi

Если ваши условные операторы содержат команду проверки ([), как показано здесь, можно использовать символы -a и -o вместо конструкций && и ||, о чем рассказано в следующем разделе.

11.5.5. Проверка условий

Вы увидели, как работает команда [:, код выхода равен 0, если условие проверки истинно, и не равен 0, если проверка завершена неудачно. Вы знаете также, как проверить равенство строк с помощью команды [ str1 = str2 ]. Помните о том, что сценарии оболочки хорошо приспособлены для операций с целыми файлами, поскольку наиболее полезные проверки с помощью команды [ затрагивают свойства файлов. Например, следующая строка проверяет, является ли файл file обычным файлом (а не каталогом или специальным файлом):

[ -f file ]

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

for filename in *; do

    if [ -f $filename ]; then

        ls -l $filename

        file $filename

    else

       echo $filename is not a regular file.

    fi

done

Можно выполнить инверсию условия, поместив оператор ! перед аргументами команды проверки. Например, условие [ ! –f file ] возвращает значение true, если файл file не является обычным файлом. Кроме того, флаги -a и -o являются логическими операторами «и» и «или» (например, [ -f file1 –a file2 ]).

примечание

Поскольку команда test так широко применяется в сценариях, во многих версиях оболочки Bourne shell (включая версию bash) эта команда является встроенной. Это может ускорить выполнение сценариев, так как оболочке не приходится для каждой проверки запускать отдельную команду.

Существуют десятки операторов проверки, и все они попадают в одну из трех основных категорий: проверка файлов, проверка строк и арифметическая проверка. Интерактивное руководство info содержит всю необходимую документацию, однако страница руководства test(1) позволит быстрее навести справки. В следующих разделах приведены общие сведения об основных видах проверок.

Проверка файлов

Большинство проверок файлов, вроде -f, называется унарными операциями, поскольку им необходим только один аргумент: файл, который следует проверить. Вот две важные проверки файлов:

• -e — возвращает значение true, если файл существует;

• -s — возвращает значение true, если файл непyстой.

Многие операции отслеживают тип файла, это значит, что они способны определить, является ли что-либо обычным файлом, каталогом или специальным устройством, как перечислено в табл. 11.1. Есть также несколько унарных операций, которые проверяют права доступа к файлу, как указано в табл. 11.2 (см. также обзор прав доступа в разделе 2.17).

Таблица 11.1. Операторы проверки типа файла

Оператор

Условие проверки

-f

Обычный файл

-d

Каталог

-h

Символическая ссылка

-b

Блочное устройство

-c

Символьное устройство

-p

Именованный канал

-s

Сокет

примечание

Команда test отслеживает символические ссылки (кроме варианта -h), то есть если ссылка link является символической ссылкой на обычный файл, проверка [ -f link ] возвратит код выхода 0 (true).

Таблица 11.2. Операторы проверки прав доступа к файлу

Оператор

Оператор

-r

Для чтения

-w

Для записи

-x

Исполняемый

-u

Setuid

-g

Setgid

-k

«Закрепленный»

Наконец, три бинарных оператора (это проверки, которым необходимы два файла в качестве аргументов) используются при проверке файлов, но такие проверки не слишком распространены. Посмотрите на такую команду, которая содержит оператор -nt («более поздний, чем»):