В командном языке bash операторы if и while могут использовать в качестве условия код завершения произвольной программы. Код ответа 0 интерпретируется как "истина", любой другой - как "ложь". Вместо if можно использовать операторы условного выполнения cmd1 && cmd2 - выполнить cmd2 если cmd1 завершилась успешно и cmd1 || cmd2 - выполнить cmd2 если cmd1 завершилась неуспешно.
Пример:
if grep --silent aaa file; then echo file \"file\" contain \"aaa\"; fi
grep --silent aaa file && echo file \"file\" contain \"aaa\"
grep --silent aaa file || echo file \"file\" not contain \"aaa\"
Для того, чтобы в качестве условия можно было бы писать традиционные выражения, была придумана команда test. Команда получает операторы и операнды в виде отдельных аргументов командной строки, вычисляет логическое условие и возвращает 0, 1 или 2 (в случае синтаксической ошибки).
Пример:
test "abc" = "cde" || echo "abc" not equal "cde"
Для красоты записи программа test имеет ещё одно имя - [ и вспомогательный последний аргумент ] . Две строчки ниже эквивалентны:
if test 1 -gt 0; then echo 1 \> 0;fi
if [ 1 -gt 0 ]; then echo 1 \> 0;fi
Аргументы команды test подвергаются обычным подстановкам и разбиением на слова, что часто приводит к ошибкам:
[ "A" > "B" ] # неправильно
[ "A" \> "B" ] # правильно
[ $A = HELLO ] # ошибка если переменная A не определена, содержит пробелы или символы подстановки
[ "$A" = HELLO ] # ошибка если $A начинается с минуса. Например -eq
[ x"$A" = xHELLO ] # прием, позволяющий корректно провести сравнение
Для того, чтобы преодолеть указанные проблемы в язык введена синтаксическая конструкция [[expr]], которая разбирает выражение expr по тем же правилам, что и команда test, но при этом внутри скобок не производится подстановка имен файлов, перенаправление ввода/вывода и разбиение содержимого переменных на слова.
[[expr]] в отличие от [ expr ] не является независимой командой, что можно увидеть на примерах:
\[ -e file \] # нормально
[ -e file ] # то же самое
\[\[ -e file \]\] # [[: command not found
[[ -e file ]] # нормально
Набор операторов test и [[
Проверки объектов файловой системы: op path
-S сокет
-r доступен на чтение
Проверка строк: op string
Сравнение строк: string1 op string2
Сравнение чисел: num1 op num2
Группировка: (expr)
Отрицание: ! expr
Логические операции в test: expr1 op expr2
Логические операции в [[: expr1 op expr2