Двойные квадратные скобки vs одиночные в 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‑руководстве, двойные скобки не разбивают строковые переменные, содержащие пробелы, что устраняет необходимость двойного экранирования во многих случаях.
# Одиночные скобки требуют аккуратного экранирования
if [ "$user" = "John Doe" ] ; then
echo "Hello, $user"
fi
# Двойные скобки более гибкие
if [[ $user = "John Doe" ]] ; then
echo "Hello, $user"
fi
Меньшая необходимость в экранировании
Оригинальный пример от вашего коллеги можно упростить, используя двойные скобки:
# Оригинал с одиночными скобками (требует аккуратного экранирования)
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‑системами и реализациями оболочек одиночные скобки являются более консервативным вариантом.
Практические примеры и лучшие практики
Сравнение строк
# Одиночные скобки — требуется аккуратное экранирование
if [ "$name" = "John" ] ; then
echo "Hello John"
fi
# Двойные скобки — более гибкие
if [[ $name = "John" ]] ; then
echo "Hello John"
fi
Проверка файлов
# Оба работают для базовой проверки файлов
if [ -f "/path/to/file" ] ; then
echo "File exists"
fi
if [[ -f "/path/to/file" ]] ; then
echo "File exists"
fi
Логические операторы
Двойные скобки позволяют использовать более интуитивный синтаксис логических операторов:
# Одиночные скобки — операторы требуют экранирования
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 обоснованы и включают:
- Улучшенная безопасность – автоматическое предотвращение разбиения слов и подстановки подстановочных символов снижает частые ошибки скриптов.
- Уменьшение сложности экранирования – меньше необходимости в явном экранировании делает код чище и более читаемым.
- Более мощные операторы – доступ к дополнительным операторам и функциям для сложной условной логики.
- Современный синтаксис – более интуитивный синтаксис логических операторов и расширенные возможности сопоставления шаблонов.
Для скриптов, специфичных для Bash, где не требуется максимальная портативность к другим оболочкам, двойные скобки действительно являются лучшим выбором. Однако для скриптов, которые должны работать на различных реализациях оболочек или в системах с ограниченными возможностями, одиночные скобки остаются более безопасным вариантом.
Ключевое — понять обе конструкции и выбирать подходящую в зависимости от требований к совместимости, безопасности и функциональности.
Источники
- Using Square Brackets in Bash - GeeksforGeeks
- Bash Square Brackets: Unlocking Their Power in Bash
- bash Double Bracket: A Quick Guide to Enhanced Syntax
- Bash Scripting: Understanding the Use of Parentheses, Brackets, and Braces
- Bash Operators in Linux: A Comprehensive Guide
- Conditions in bash scripting (if statements) | Medium
- Using the -ge Operator in Bash: A Comprehensive Guide
- Bash Scripting vs Shell Scripting: Differences, Examples, and Comparisons
- How To Use Bash If Statements (With Code Examples) | Zero To Mastery
- Bash if…else Statement Tutorial: Using [[ ]], elif, and Logical Operators