junior
Как работают условные выражения в bash?
Условные выражения в bash — это конструкции для проверки условий (существование файлов, сравнение строк и чисел, логические операции). Bash предоставляет три формы: test, [ ] (POSIX-совместимые) и [[ ]] (расширенная bash-конструкция).
test и [ ] — POSIX-совместимые конструкции
test и [ ] — это одно и то же ([ — это программа, ] — обязательный последний аргумент):
Пример
test -f file.txt # Эквивалентно:
[ -f file.txt ] # Между [ и ] обязательны пробелы!
[[ ]] — расширенная конструкция bash (рекомендуется)
[[ ]] — встроенная конструкция bash, более безопасная и мощная:
Пример
[[ -f file.txt ]] # Безопасна при пустых переменных, поддерживает glob и regex
Проверки файлов
Пример
[[ -f file.txt ]] # Файл существует и является обычным файлом
[[ -d directory ]] # Существует и является директорией
[[ -e path ]] # Существует (любой тип)
[[ -r file.txt ]] # Файл доступен для чтения
[[ -w file.txt ]] # Файл доступен для записи
[[ -x script.sh ]] # Файл исполняемый
[[ -s file.txt ]] # Файл существует и не пуст
[[ -L link ]] # Является символической ссылкой
[[ file1 -nt file2 ]] # file1 новее file2 (newer than)
[[ file1 -ot file2 ]] # file1 старше file2 (older than)
Сравнение строк
Пример
[[ "$str1" == "$str2" ]] # Строки равны
[[ "$str1" != "$str2" ]] # Строки не равны
[[ "$str1" < "$str2" ]] # Лексикографически меньше
[[ -z "$str" ]] # Строка пуста (zero length)
[[ -n "$str" ]] # Строка не пуста (non-zero length)
[[ "$str" == *.java ]] # Glob-паттерн (только в [[ ]])
[[ "$str" =~ ^[0-9]+$ ]] # Регулярное выражение (только в [[ ]])
Сравнение чисел
Пример
[[ $a -eq $b ]] # Равно (equal)
[[ $a -ne $b ]] # Не равно (not equal)
[[ $a -lt $b ]] # Меньше (less than)
[[ $a -le $b ]] # Меньше или равно (less or equal)
[[ $a -gt $b ]] # Больше (greater than)
[[ $a -ge $b ]] # Больше или равно (greater or equal)
# Арифметическое сравнение (альтернатива — удобнее для чисел)
(( a == b ))
(( a > b ))
(( a < b ))
Логические операции
Пример
# В [[ ]] — внутри одной конструкции
[[ condition1 && condition2 ]] # И (AND)
[[ condition1 || condition2 ]] # ИЛИ (OR)
[[ ! condition ]] # НЕ (NOT)
# В [ ] — через отдельные вызовы (другой синтаксис!)
[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]
[ ! condition ]
Сравнение [ ] и [[ ]]
| Возможность | [ ] |
[[ ]] |
|---|---|---|
| POSIX-совместимость | Да | Нет (только bash/zsh/ksh) |
Glob-паттерны (*.java) |
Нет | Да |
Регулярные выражения (=~) |
Нет | Да |
&& / || внутри |
Нет | Да |
| Безопасность при пустых переменных | Требует кавычки | Кавычки необязательны |
Практический пример
Пример
#!/bin/bash
ENV="${1:-dev}"
if [[ "$ENV" =~ ^(dev|staging|production)$ ]]; then
echo "Deploying to $ENV..."
else
echo "Unknown environment: $ENV"
echo "Usage: $0 [dev|staging|production]"
exit 1
fi
if [[ -f "config-${ENV}.yml" ]]; then
echo "Using config: config-${ENV}.yml"
else
echo "Config not found, using defaults"
fi
На собеседовании: рекомендуйте
[[ ]]как основную конструкцию, объясните преимущества: безопасность при пустых переменных, поддержка glob и regex,&&/||внутри. Если спрашивают про POSIX-совместимость (скрипты дляsh, а неbash), тогда используйте[ ].