Гид по технологиям

Bash if: условная логика в Bash-скриптах

7 min read Linux Обновлено 25 Dec 2025
Bash if — условная логика в Bash
Bash if — условная логика в Bash

Ноутбук с Linux, в терминале видна командная строка и фоновый узор в виде глобуса и двоичного водяного знака

Быстрые ссылки

  • Что такое условное выполнение?
  • Простой пример if
  • Конструкция elif
  • Варианты условных тестов
  • Вложенные if
  • Когда использовать case вместо if

Краткое содержание

Конструкция if в Bash позволяет задавать условные выражения в формате if then fi. Добавление elif даёт дополнительные проверки, а else — обработку случая, когда ни одно условие не выполнено. Условные ветвления необходимы для скриптов любой практической сложности.

Важно: условные выражения — это способ задать вопрос скрипту и получить разные ответы в виде разных блоков кода.

Что такое условное выполнение?

Условное выполнение — это возможность программы менять поток выполнения в зависимости от истинности выражения. В Bash это обычно делается с помощью if-оператора. Простая мысль: если условие истинно, выполнить этот блок, иначе — выполнить другой.

Условие может проверять:

  • значение переменной;
  • наличие файла или каталога;
  • сравнение строк или чисел;
  • результат команды (код возврата).

Условная логика даёт программам гибкость: без неё скрипт выполняет только одну последовательность действий и не может адаптироваться к реальным условиям.

Простой пример if

Классическая форма простейшего if:

if [ this-condition-is-true ]
then
    execute-these-statements
fi

Если условие истинно, выполняется блок после then. Часто запись выглядит компактнее:

if [ this-condition-is-true ]; then
    execute-these-statements
fi

Несколько практических замечаний:

  • if завершается ключевым словом fi.
  • Между [ и условием и между условием и ] должны быть пробелы.
  • Если then в той же строке, используйте ; после ].

Добавим else, чтобы обработать ложный случай:

if [ this-condition-is-true ]; then
    execute-these-statements
else
    execute-these-statements-instead
fi

Пример с проверкой возраста клиента (файл if-age.sh):

#!/bin/bash

customer_age=25

if [ $customer_age -ge 21 ]; then
    echo 'Проходите.'
else
    echo 'Вам нельзя входить.'
fi

Сделайте файл исполняемым:

chmod +x if-age.sh
./if-age.sh

Если заменить customer_age=18 и запустить снова, выполнится ветка else.

Конструкция elif

elif добавляет промежуточные проверки — их может быть сколько угодно. Они проверяются по порядку; при первом истинном условии выполняется соответствующий блок, остальные игнорируются. Если ни одно из условий не истинно и есть else, выполняется он.

Пример: проверка чётности числа (if-even.sh):

#!/bin/bash

echo -n 'Введите число: '
read number

if [ $number -eq 0 ]; then
    echo 'Вы ввели ноль. Ноль — чётное число.'
elif [ $(($number % 2)) -eq 0 ]; then
    echo "Вы ввели $number. Это чётное число."
else
    echo "Вы ввели $number. Это нечётное число."
fi

Для запуска:

chmod +x if-even.sh
./if-even.sh

Запуск скрипта if-even.sh с разными вводами

Варианты условных тестов

Запись [ ... ] — это сокращение для программы test. Поэтому доступны все операции test.

Наиболее часто используемые тесты:

  • ! expression — истинно, если выражение ложно.
  • -n string — истинно, если длина строки > 0.
  • -z string — истинно, если строка пустая.
  • string1 = string2 — истинно, если строки идентичны (символ за символом).
  • string1 != string2 — истинно, если строки различаются.
  • integer1 -eq integer2 — числовое равенство.
  • integer1 -gt integer2 — числовая операция: больше.
  • integer1 -lt integer2 — числовая операция: меньше.
  • -d directory — существует каталог.
  • -e file — существует файл.
  • -s file — файл существует и его размер > 0.
  • -r file — файл существует и доступен для чтения.
  • -w file — файл существует и доступен для записи.
  • -x file — файл существует и доступен для выполнения.

Важно понимать разницу между = и -eq: первая сравнивает как строки, вторая — как числа. Пример:

test 1 = 001
echo $?  # вернёт 1 — ложь (строки разные)

test 1 -eq 001
echo $?  # вернёт 0 — истина (числа равны)

Использование программы test для разных сравнений

Для шаблонного соответствия используйте двойные скобки [[ ]] — внутри них доступны шаблоны и несколько дополнительных возможностей:

#!/bin/bash

if [[ $USER == *ve ]]; then
    echo "Привет, $USER"
else
    echo "$USER не оканчивается на 've'"
fi

[[ ]] защищает от некоторых неожиданностей, связанных с разбиением полей и подстановкой имен файлов (word splitting и pathname expansion).

Вложенные if

Можно вкладывать if внутрь другого if. Это допустимо, но ухудшает читабельность при глубине больше 2–3 уровней. Если вы оказались в глубокой вложенности, подумайте о реструктуризации логики (функции, case, таблицы соответствия).

Пример: определение рабочего времени магазина (if-shop.sh):

#!/bin/bash

# получить день недели числом 1..7 (1 — понедельник)
day=$(date +"%u")

if [ $day -le 6 ]; then
    # магазин открыт
    if [ $day -eq 3 ]; then
        # среда — сокращённый день
        echo 'По средам открыты только утром.'
    else
        echo 'Мы открыты весь день.'
    fi
else
    # воскресенье — выходной
    echo 'Воскресенье — выходной.'
fi

Запускайте и тестируйте, меняя системное время или сами значения переменной day.

Запуск скрипта if-shop.sh при настройке системных дат: будний день, среда, воскресенье

Совет: для сложной логики вместо глубокой вложенности используйте ранний выход из функции/скрипта (guard clauses) или перевод условий в отдельные функции.

Когда использовать case вместо if

if — универсальный инструмент, но не всегда оптимален. Если у вас большая ветвящаяся логика по значению одной переменной, case часто проще и читабельнее.

Пример шаблона case:

case $var in
    pattern1)
        commands ;;
    pattern2)
        commands ;;
    *)
        default_commands ;;
esac

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

Альтернативные подходы и когда if не подходит

  • Для множественного сопоставления по одному значению — используйте case.
  • Для простых бинарных решений можно использовать логические операторы && и || для компактного кода: command && echo 'OK' || echo 'ERROR'.
  • Для проверки набора условий удобна таблица соответствий (ассоциативный массив): ключ → обработчик.
  • Для потоковой обработки большого объёма данных чаще применяют фильтрацию с помощью внешних инструментов (awk, sed) вместо вложенных if.

Примеры неудачного применения if:

  • Глубокая вложенность >3 уровней; код становится нечитаемым.
  • Повторяющиеся условия по одной и той же переменной; case компактнее.
  • Слишком много текстовых сравнений, где лучше применить регулярные выражения.

Ментальные модели и эвристики

  • «Проверяй по одному факту»: каждая ветка if должна решать один аспект логики.
  • «Ранний выход»: если условие делает дальнейшую работу ненужной, заверши функцию сразу.
  • «Сначала плохие сценарии»: сначала обрабатывайте ошибки и исключения, потом основной путь.

Эти правила улучшают читабельность и тестируемость.

Справочник и краткая памятка (Cheat sheet)

  • Синтаксис:
if [ condition ]; then
    commands
elif [ condition2 ]; then
    commands
else
    commands
fi
  • Используйте [[ ]] для шаблонов и безопасных выражений.
  • Числовые сравнения: -eq, -ne, -gt, -ge, -lt, -le.
  • Строковые сравнения: =, !=, -z, -n.
  • Проверки файлов: -e, -f, -d, -r, -w, -x, -s.
  • Получение кода возврата последней команды: $?.
  • Проверка результата команды непосредственно в if: if command; then ... fi (истина при коде возврата 0).

Шаблоны и сниппеты

Проверка существования файла:

if [ -e /path/to/file ]; then
    echo 'Файл существует'
else
    echo 'Файла нет'
fi

Проверка строки на пустоту:

if [ -z "$var" ]; then
    echo 'Пусто'
fi

Компактная запись через логические операторы:

command && echo 'Успех' || echo 'Неудача'

Но будьте осторожны: в сложных случаях &&/|| могут вести себя не так, как ожидалось, если команды внутри возвращают разные коды выхода.

Проверки и критерии приёмки

  • Скрипт корректно обрабатывает все ожидаемые входные данные.
  • Для каждой ветки if есть тесты: позитивные и негативные сценарии.
  • Нет вложенности более трёх уровней без необходимости.
  • Для пользовательских сообщений используются понятные тексты; внутренняя логика вынесена в функции.

Минимальные тесты для примеров выше:

  • if-age.sh: проверка для age=25 и age=18.
  • if-even.sh: проверки для 0, чётного и нечётного числа.
  • if-shop.sh: проверка для weekday, wednesday, sunday.

Рольные чек-листы

Разработчик:

  • Явно обрабатывать ошибки ввода.
  • Вынести повторяющуюся логику в функции.
  • Добавить комментарии и пример запуска.

Системный администратор:

  • Проверить права на выполнение скрипта (chmod +x).
  • Проверить, что скрипт вызывается с нужной оболочкой (shebang).

Тестировщик:

  • Подготовить набор входных значений, покрывающих все ветви.
  • Автоматизировать запуск и сравнение вывода.

Диаграмма принятия решения (Mermaid)

flowchart TD
  A[Есть ли несколько совпадающих значений одной переменной?] -->|Да| B[Используйте case]
  A -->|Нет| C[Нужно ли проверять права/файлы/возврат команд?]
  C -->|Да| D[Используйте if с тестами '-e, -x, код возврата']
  C -->|Нет| E[Нужно ли шаблонное соответствие?]
  E -->|Да| F[Используйте [[ ]] для шаблонов]
  E -->|Нет| G[Используйте простые if или логические операторы]

Матрица сравнения: if vs case vs [[ ]]

  • if: гибкость, подходит для числовых и булевых проверок, проверки кодов возврата.
  • case: удобство при множественном сопоставлении по одному значению; улучшает читабельность.
  • [[ ]]: расширенные проверки строк, шаблоны; более безопасно в сценариях с подстановкой.

Безопасность и права

  • Всегда проверяйте пути и права доступа перед выполнением операций с файлами.
  • Не доверяйте входным данным: экранируйте переменные, используйте кавычки при подстановке.
  • Для операций от имени root явно документируйте причины повышения привилегий.

Важно: отсутствие кавычек вокруг переменных — частая причина ошибок и уязвимостей (word splitting, globbing).

Глоссарий (одной строкой)

  • if: базовый оператор ветвления в Bash.
  • then/else/elif/fi: ключевые слова для управления ветками.
  • test/[]: утилита для проверки выражений.
  • [[ ]]: расширённая версия тестовых скобок с поддержкой шаблонов.

Когда всё собрано: методика разработки

  1. Напишите минимальную проверку, которая решает основной кейс.
  2. Добавьте проверки ошибок и else-ветки.
  3. Покройте код тестами: позитив и негатив.
  4. Рефакторите: вынесите повторяющуюся логику в функции или выберите case.
  5. Проверьте поведение при некорректных входных данных.

Когда if не справляется — примеры

  • Большой набор условий по одному параметру → case будет понятнее.
  • Обработка совпадений по сложным регулярным шаблонам — лучше grep/awk или [[ =~ ]].
  • Очень производительные потоки данных — фильтруйте внешними утилитами.

Краткое резюме

  • if — основной инструмент условной логики в Bash.
  • Используйте [[ ]] для шаблонов и безопасных строковых сравнений.
  • elif и else дают гибкость; case упрощает множественное сопоставление.
  • Избегайте глубокой вложенности, экранируйте переменные и покрывайте тестами.

Важно: простая, тестируемая и читаемая логика всегда выигрывает у хитроумных кратких конструкций.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

ImageFX от Google — быстрое руководство
Инструменты ИИ

ImageFX от Google — быстрое руководство

Как исправить дрейф стика контроллера
Гайды

Как исправить дрейф стика контроллера

Как увеличить хранилище iCloud — инструкция
Руководство

Как увеличить хранилище iCloud — инструкция

Проверка и замена батарейки CMOS на ПК
Компьютеры

Проверка и замена батарейки CMOS на ПК

Создать визитку в Microsoft Word
Маркетинг

Создать визитку в Microsoft Word

Как найти и использовать функции в Excel
Excel

Как найти и использовать функции в Excel