Другое

Двойные квадратные скобки vs одиночные в Bash: Полное руководство

Узнайте, почему двойные скобки [[ ]] в Bash предпочтительнее одиночных [ ]: безопасность, упрощённые кавычки и более мощные операторы.

Преференция двойных квадратных скобок [[ ]] над одиночными [ в Bash?

Коллега недавно в код‑ревью утверждал, что конструкция [[ ]] предпочтительнее, чем [ ] в таких конструкциях, как:

bash
if [ "`id -nu`" = "$someuser" ] ; then
     echo "I love you madly, $someuser"
fi

Он не смог предоставить обоснование. Есть ли такое?

Двойные квадратные скобки [[ ]] обычно предпочтительнее одиночных квадратных скобок [ ] в Bash‑скриптах благодаря улучшенной функциональности, повышенной безопасности и более современному синтаксису. Причины этого выбора включают более надёжную защиту от разбиения слов, более мощные операторы и уменьшение необходимости явного экранирования в большинстве случаев.

Содержание

Ключевые различия между [[ ]] и [ ]

Основное различие между этими конструкциями заключается в их происхождении и возможностях:

  • Одиночные квадратные скобки [ ] являются POSIX‑совместимыми и работают во всех типах оболочек, включая Bourne, Korn и Bash. По сути они вызывают команду test.

  • Двойные квадратные скобки [[ ]] специфичны для Bash и предоставляют расширенную функциональность с улучшенным синтаксисом и дополнительными возможностями.

Согласно Linuxconfig.org, операторы в левой колонке работают как с одиночными, так и с двойными скобками, а операторы в правой колонке работают только с двойными скобками, что демонстрирует более широкий диапазон возможностей двойных скобок.

Преимущества двойных квадратных скобок [[ ]]

Улучшенная защита от разбиения слов

Одно из самых значимых преимуществ двойных скобок — их способность предотвращать случайное разбиение слов. Как описано в Medium‑руководстве, двойные скобки не разбивают строковые переменные, содержащие пробелы, что устраняет необходимость двойного экранирования во многих случаях.

bash
# Одиночные скобки требуют аккуратного экранирования
if [ "$user" = "John Doe" ] ; then
    echo "Hello, $user"
fi

# Двойные скобки более гибкие
if [[ $user = "John Doe" ]] ; then
    echo "Hello, $user"
fi

Меньшая необходимость в экранировании

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

bash
# Оригинал с одиночными скобками (требует аккуратного экранирования)
if [ "`id -nu`" = "$someuser" ] ; then
     echo "I love you madly, $someuser"
fi

# Улучшено с двойными скобками (меньше экранирования)
if [[ $(id -nu) = $someuser ]] ; then
     echo "I love you madly, $someuser"
fi

Согласно ZeroToMastery, двойные скобки предотвращают разбиение слов, поэтому не нужно двойное экранирование строковых переменных, хотя это всё равно хорошая практика.

Более мощные операторы

Двойные скобки предоставляют доступ к дополнительным операторам и функциям, недоступным в одиночных скобках. Bashcommands.com объясняет, что двойные скобки предлагают более широкую функциональность и упрощённый синтаксис для некоторых задач, связанных со строковыми и файловыми сравнениями.

Лучшее сопоставление шаблонов

Двойные скобки поддерживают регулярные выражения и более сложные возможности сопоставления шаблонов, что делает их незаменимыми для сложной условной логики.


Когда использовать одиночные квадратные скобки [ ]

Несмотря на преимущества двойных скобок, существуют конкретные сценарии, когда одиночные скобки остаются предпочтительными:

Кросс‑оболочная совместимость

Если ваш скрипт должен работать на системах с другими оболочками, такими как dash (по умолчанию /bin/sh в Debian/Ubuntu), одиночные скобки являются более безопасным выбором, поскольку они POSIX‑совместимы.

Требования к портативности

Для максимальной портативности между различными Unix‑системами и реализациями оболочек одиночные скобки являются более консервативным вариантом.


Практические примеры и лучшие практики

Сравнение строк

bash
# Одиночные скобки — требуется аккуратное экранирование
if [ "$name" = "John" ] ; then
    echo "Hello John"
fi

# Двойные скобки — более гибкие
if [[ $name = "John" ]] ; then
    echo "Hello John"
fi

Проверка файлов

bash
# Оба работают для базовой проверки файлов
if [ -f "/path/to/file" ] ; then
    echo "File exists"
fi

if [[ -f "/path/to/file" ]] ; then
    echo "File exists"
fi

Логические операторы

Двойные скобки позволяют использовать более интуитивный синтаксис логических операторов:

bash
# Одиночные скобки — операторы требуют экранирования
if [ -f "file1" ] && [ -f "file2" ] ; then
    echo "Both files exist"
fi

# Двойные скобки — более чистый синтаксис
if [[ -f "file1" && -f "file2" ]] ; then
    echo "Both files exist"
fi

Совместимость

Хотя двойные скобки предлагают значительные преимущества, важно учитывать:

Поддержка оболочки

Двойные скобки [[ ]] поддерживаются Bash, Zsh и Ksh, но не поддерживаются POSIX‑совместимыми оболочками, такими как dash. Если ваш скрипт может выполняться на системах, где /bin/sh указывает на dash, лучше использовать одиночные скобки.

Устаревшие системы

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


Вывод

Причины предпочитать двойные квадратные скобки [[ ]] над одиночными квадратными скобками [ ] в Bash обоснованы и включают:

  1. Улучшенная безопасность – автоматическое предотвращение разбиения слов и подстановки подстановочных символов снижает частые ошибки скриптов.
  2. Уменьшение сложности экранирования – меньше необходимости в явном экранировании делает код чище и более читаемым.
  3. Более мощные операторы – доступ к дополнительным операторам и функциям для сложной условной логики.
  4. Современный синтаксис – более интуитивный синтаксис логических операторов и расширенные возможности сопоставления шаблонов.

Для скриптов, специфичных для Bash, где не требуется максимальная портативность к другим оболочкам, двойные скобки действительно являются лучшим выбором. Однако для скриптов, которые должны работать на различных реализациях оболочек или в системах с ограниченными возможностями, одиночные скобки остаются более безопасным вариантом.

Ключевое — понять обе конструкции и выбирать подходящую в зависимости от требований к совместимости, безопасности и функциональности.

Источники

  1. Using Square Brackets in Bash - GeeksforGeeks
  2. Bash Square Brackets: Unlocking Their Power in Bash
  3. bash Double Bracket: A Quick Guide to Enhanced Syntax
  4. Bash Scripting: Understanding the Use of Parentheses, Brackets, and Braces
  5. Bash Operators in Linux: A Comprehensive Guide
  6. Conditions in bash scripting (if statements) | Medium
  7. Using the -ge Operator in Bash: A Comprehensive Guide
  8. Bash Scripting vs Shell Scripting: Differences, Examples, and Comparisons
  9. How To Use Bash If Statements (With Code Examples) | Zero To Mastery
  10. Bash if…else Statement Tutorial: Using [[ ]], elif, and Logical Operators
Авторы
Проверено модерацией
Модерация