Конструкция if test condition-true является точным эквивалентом конструкции if [ condition-true ], где левая квадратная скобка [ выполняет те же действия, что и команда test. Закрывающая правая квадратная скобка ] не является абсолютно необходимой, однако, более новые версии Bash требуют ее наличие.
Команда test -- это встроенная команда Bash, которая выполняет проверки файлов и производит сравнение строк. Таким образом, в Bash-скриптах, команда test не вызывает внешнюю (/usr/bin/test) утилиту, которая является частью пакета sh-utils. Аналогично, [ не производит вызов утилиты /usr/bin/[, которая является символической ссылкой на /usr/bin/test.
bash$ type test
test is a shell builtin
bash$ type '['
[ is a shell builtin
bash$ type '[['
[[ is a shell keyword
bash$ type ']]'
]] is a shell keyword
bash$ type ']'
bash: type: ]: not found
Пример 7-2. Эквиваленты команды test -- /usr/bin/test, [ ], и /usr/bin/[
#!/bin/bash
echo
if test -z "$1"
then
echo "Аргументы командной строки отсутствуют."
else
echo "Первый аргумент командной строки: $1."
fi
echo
if /usr/bin/test -z "$1" # Дает тот же рузультат, что и встроенная команда "test".
then
echo "Аргументы командной строки отсутствуют."
else
echo "Первый аргумент командной строки: $1."
fi
echo
if [ -z "$1" ] # Функционально идентично вышеприведенному блоку кода.
# if [ -z "$1" эта конструкция должна работать, но...
#+ Bash выдает сообщение об отсутствующей закрывающей скобке.
then
echo "Аргументы командной строки отсутствуют."
else
echo "Первый аргумент командной строки: $1."
fi
echo
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 не найден."