Тестирование строк в bash: операторы -z и -n
В этой статье объяснено, как проверять пустые и непустые строки в bash с помощью операторов -z и -n. Приведены готовые примеры скриптов, объяснены частые ошибки, советы по безопасности и контрольные списки для практического использования.
Краткое введение
В bash есть простые тесты для проверки строки на пустоту или на наличие символов. Оператор -z возвращает истину, если строка имеет длину 0. Оператор -n возвращает истину, если строка имеет ненулевую длину. Эти проверки часто используются в условных выражениях if для управления потоками выполнения в скриптах.
Ключевые понятия в одну строку:
- -z: истина, если строка пустая (нулевой длины)
- -n: истина, если строка не пустая
- Всегда берите переменные в кавычки при тесте, чтобы избежать ошибок с пробелами и раскрытием подстановки

Быстрая справка
- Синтаксис с одинарными скобками: if [ -z “$var” ]; then … fi
- Синтаксис с двойными скобками для арифметики и расширений: [[ -n $var ]] и т. п.
- Рекомендуется использовать конструкцию [[ … ]] в bash, она безопаснее для сравнения строк
Примеры: подготовка файла CheckString.sh
Создадим файл CheckString.sh в домашней директории. Команда для создания файла:
$ touch CheckString.sh
Ниже идут несколько вариантов содержимого файла для разных задач. Во всех примерах используйте chmod +x CheckString.sh если хотите запускать как ./CheckString.sh, или запускайте bash CheckString.sh
Пример 1. if -n когда строка пустая
Цель: показать, что оператор -n вернёт false для пустой строки и выполнит ветку else.
Содержимое CheckString.sh:
#!/usr/bin/env bash
StdName=
if [ -n "$StdName" ]; then
echo Hy! $StdName
else
echo Sorry! You have no name
fiЗапуск:
$ bash CheckString.shОжидаемый вывод в терминале:
Sorry! You have no nameПояснение: переменная StdName инициализирована пустой строкой. Оператор -n проверяет ненулевую длину, поэтому условие ложно и выполняется else.
Пример 2. if -n когда строка не пустая
Изменим только присвоение StdName:
#!/usr/bin/env bash
StdName="Aqsa Yasin"
if [ -n "$StdName" ]; then
echo Hy! $StdName
else
echo Sorry! You have no name
fiЗапуск и ожидаемый вывод:
$ bash CheckString.sh
Hy! Aqsa YasinПояснение: теперь -n возвращает истину, так как длина StdName больше нуля.
Пример 3. if -z когда строка пустая
Используем -z, который истинен на пустой строке:
#!/usr/bin/env bash
StdName=
if [ -z "$StdName" ]; then
echo Sorry You have no name
else
echo Hy! $StdName
fiЗапуск:
$ bash CheckString.sh
Sorry You have no nameПример 4. if -z когда строка не пустая
Если StdName содержит значение, -z будет ложен и выполнится else:
#!/usr/bin/env bash
StdName="Aqsa Yasin"
if [ -z "$StdName" ]; then
echo Sorry You have no name
else
echo Hy $StdName
fiОжидаемый вывод:
Hy Aqsa YasinПример 5. if -z с вводом пользователя
В этом варианте скрипт запрашивает строку у пользователя и проверяет пустоту. Если ввод пуст, просит ввести снова.
#!/usr/bin/env bash
read -p "Enter your name: " input
if [ -z "$input" ]; then
echo "You entered nothing, please try again"
read -p "Enter your name: " input
fi
if [ -z "$input" ]; then
echo "No name provided, exiting"
exit 1
else
echo "The string you entered is: $input"
fi
Пояснение: первый read позволяет пользователю ввести строку. Если строка пустая, скрипт запрашивает второй раз. После повторной проверки скрипт либо выводит введённую строку, либо завершает работу с ошибкой.
Частые ошибки и нюансы
Не брать переменные в кавычки
- Неправильно: if [ -z $var ]; then
- Правильно: if [ -z “$var” ]; then
Без кавычек значение с пробелами или значение, равное пустой строке, может привести к синтаксической ошибке или неправильной работе условия.
Пробелы вокруг квадратных скобок
- Требуется пробел после [ и перед ] при использовании одинарных скобок [ ]
- Правильно: if [ -n “$var” ]; then
Разница между [ … ] и [[ … ]]
- [[ … ]] — расширенная конструкция bash, менее подвержена неожиданному поведению при содержимом переменных, поддерживает дополнительные операторы и паттерны
- Можно писать: if [[ -z $var ]]; then
Пробельные и невидимые символы
- Строка из единственного пробела не пустая. -z вернёт false. Для проверки на строку, состоящую только из пробелов, примените дополнительную нормализацию, например удаление пробелов:
trimmed=${var//[[:space:]]/}
if [ -z "$trimmed" ]; then
echo "строка пуста или состоит только из пробелов"
fi- Перенаправление и чтение из stdin
- read считывает до символа новой строки, но если ввод идёт из файла или канала, поведение остаётся тем же. Учитывайте, что в интерактивных сессиях read может быть прерван.
Практические советы и лучшие практики
- Всегда берите переменные в двойные кавычки при тестах: “$var”. Это предотвращает ошибки с пустыми строками и пробелами.
- Когда пишете скрипт для bash, отдавайте предпочтение [[ … ]] для проверки условий, если нет требований совместимости с /bin/sh.
- Если ожидается ввод пользователя, валидируйте и очищайте данные от управляющих символов.
- Для логирования избегайте вывода чувствительных данных в явном виде.
Ментальные модели и эвристики
- Думайте о -z как о вопросе “пустая ли строка” и о -n как о вопросе “есть ли в строке хоть один символ”.
- Всегда предполагается, что строка, содержащая пробелы, не равна пустой. Если вам нужен тест “пустая или только пробелы”, предварительно удаляйте пробелы.
- Для ветвления в коде сначала проверяйте ошибочные или граничные случаи (fail fast), затем основной путь выполнения.
Когда проверки могут не сработать
- Если переменная не определена и вы используете строгие параметры оболочки set -u, доступ к несуществующей переменной вызовет ошибку. В этом случае используйте конструкцию ${var-} при подстановке.
- Если переменная содержит управляющие последовательности или нулевые символы, стандартные тесты могут работать не так, как ожидается. Для бинарных данных используйте специализированные методы.
Примеры тестов и критерии приёмки
Критерии приёмки для базового скрипта проверки строки:
- Скрипт корректно обнаруживает пустую строку при StdName=
- Скрипт корректно обнаруживает непустую строку при StdName=”value”
- Скрипт корректно запрашивает ввод пользователя и повторно просит при пустом вводе
- Все проверки выполняются без синтаксических ошибок в bash 4.x и выше
Тестовые случаи:
- StdName не объявлен
- StdName=””
- StdName=” “ (один пробел)
- StdName=”Aqsa Yasin”
- Ввод пользователя: пустой, пробелы, обычный текст
Роли и чеклисты
Для автора скрипта (разработчик):
- Добавил кавычки вокруг переменных в тестах
- Обработал случай пустого ввода
- Добавил exit с ненулевым кодом в случае критической ошибки
Для QA:
- Проверить поведение при неустановленной переменной
- Проверить поведение при пробелах в начале и в конце строки
- Проверить сценарии ввода из файлов и конвейеров
Рекомендации по безопасности и приватности
- Не логируйте ввод пользователя, если он может содержать персональные данные или секреты.
- Если скрипт запускается с повышенными правами, избегайте вывода содержимого переменных в общий лог без маскировки.
Наглядный алгоритм выбора оператора
Если нужно решить, какой оператор применить, используйте простую схему ниже.
flowchart TD
A[Есть переменная var?] --> B{Нужно ли считать строку пустой, если в ней только пробелы?}
B -- Да --> C[Удалить пробелы и проверять -z]
B -- Нет --> D{Проверять на пустоту как есть}
D -- Пустая -> E[-z true -> обработка пустоты]
D -- Не пустая -> F[-n true -> обработка значения]Сравнение: -z vs -n vs другие подходы
- -z: проверка на нулевую длину
- -n: проверка на ненулевую длину
- Проверка через [[ -v var ]] позволяет узнать, объявлена ли переменная
- Проверка через test -s файл полезна для проверки непустого файла, но не строки
Примеры из практики и альтернативные подходы
- Если нужно учитывать только видимые символы, применяйте tr, sed или parameter expansion для удаления невидимых символов перед проверкой.
- Для проверки на соответствие шаблону используйте [[ $var =~ regex ]]
Заключение
Операторы -z и -n просты и надёжны при условии правильной кавычки переменных и учёта пробельных символов. Они покрывают большинство задач по валидации строки в bash. При более сложной логике используйте нормализацию ввода и дополнительные проверки.
Краткие выводы:
- Берите переменные в кавычки
- Используйте [[ … ]] в bash для большей надёжности
- Учитывайте пробелы и невидимые символы при логике проверки
Спасибо за чтение. Применяйте эти паттерны в своих скриптах, делайте проверки явными и предсказуемыми.
Похожие материалы
Восстановление кэша значков в Windows
Стрелки не работают в Excel — быстрое решение
Шифрование USB‑накопителя с VeraCrypt
PowerShell: история команд — просмотр и сохранение
Nandroid — полная резервная копия Android