Выбрать главу

if /usr/bin/[ -z "$1" # Функционально идентично вышеприведенному блоку кода.

# if /usr/bin/[ -z "$1" ] # Работает, но выдает сообщение об ошибке.

then

echo "Аргументы командной строки отсутствуют."

else

echo "Первый аргумент командной строки: $1."

fi

echo

exit 0

Конструкция [[ ]] более универсальна, по сравнению с [ ]. Этот расширенный вариант команды test перекочевал в Bash из ksh88.

Внутри этой конструкции не производится никакой дополнительной интерпретации имен файлов и не производится разбиение аргументов на отдельные слова, но допускается подстановка параметров и команд.

file=/etc/passwd

if [[ -e $file ]]

then

echo "Файл паролей найден."

fi

Конструкция [[ ... ]] более предпочтительна, нежели [ ... ], поскольку поможет избежать некоторых логических ошибок. Например, операторы &&, ||, < и > внутри [[ ]] вполне допустимы, в то время как внутри [ ] порождают сообщения об ошибках.

Строго говоря, после оператора if, ни команда test, ни квадратные скобки ( [ ] или [[ ]] ) не являются обязательными.

dir=/home/bozo

if cd "$dir" 2>/dev/null; then # "2>/dev/null" подавление вывода сообщений об ошибках.

echo "Переход в каталог $dir выполнен."

else

echo "Невозможно перейти в каталог $dir."

fi

Инструкция "if COMMAND" возвращает код возврата команды COMMAND.

Точно так же, условие, находящееся внутри квадратных скобок может быть проверено без использования оператора if.

var1=20

var2=22

[ "$var1" -ne "$var2" ] && echo "$var1 не равно $var2"

home=/home/bozo

[ -d "$home" ] || echo "каталог $home не найден."

Внутри (( )) производится вычисление арифметического выражения. Если результатом вычислений является ноль, то возвращается 1, или "ложь". Ненулевой результат дает код возврата 0, или "истина". То есть полная противоположность инструкциям test и [ ], обсуждавшимся выше.

Пример 7-3. Арифметические выражения внутри (( ))

#!/bin/bash

# Проверка арифметических выражений.

# Инструкция (( ... )) вычисляет арифметические выражения.

# Код возврата противоположен коду возврата инструкции [ ... ] !

(( 0 ))

echo "Код возврата \"(( 0 ))\": $?." # 1

(( 1 ))

echo "Код возврата \"(( 1 ))\": $?." # 0

(( 5 > 4 )) # true

echo "Код возврата \"(( 5 > 4 ))\": $?." # 0

(( 5 > 9 )) # false

echo "Код возврата \"(( 5 > 9 ))\": $?." # 1

(( 5 - 5 )) # 0

echo "Код возврата \"(( 5 - 5 ))\": $?." # 1

(( 5 / 4 )) # Деление, все в порядке

echo "Код возврата \"(( 5 / 4 ))\": $?." # 0

(( 1 / 2 )) # Результат деления < 1.

echo "Код возврата \"(( 1 / 2 ))\": $?." # Округляется до 0.

# 1

(( 1 / 0 )) 2>/dev/null # Деление на 0.

echo "Код возврата \"(( 1 / 0 ))\": $?." # 1

# Для чего нужна инструкция "2>/dev/null" ?

# Что произойдет, если ее убрать?

# Попробуйте убрать ее и выполнить сценарий.

exit 0

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

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

-e

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

-f

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

-s

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

-d

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

-b

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

-c

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

-p

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

-h

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

-L

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

-S

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

-t

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

Этот ключ может использоваться для проверки -- является ли файл стандартным устройством ввода stdin ([ -t 0 ]) или стандартным устройством вывода stdout ([ -t 1 ]).

-r

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

-w

файл доступен для записи (пользователю, запустившему сценарий)