Какая разница между [и [[в Bash?
Я просмотрел справочную страницу bash, а [[
говорит, что использует условные выражения. Затем я просмотрел раздел "Условные выражения" и перечисляет те же операторы, что и test
(и [
).
Так интересно, в чем разница между [
и [[
в Bash?
Ответы
Ответ 1
[[
является bash улучшением команды [
. Он имеет несколько улучшений, которые делают его лучшим выбором, если вы пишете скрипты, предназначенные для bash. Мои фавориты:
-
Это синтаксическая особенность оболочки, поэтому она имеет какое-то особое поведение, которое [
не имеет. Вам больше не нужно указывать переменные вроде mad, потому что [[
обрабатывает пустые строки и строки с пробелами более интуитивно. Например, при [
вам нужно написать
if [ -f "$file" ]
чтобы правильно обрабатывать пустые строки или имена файлов с пробелами в них. При [[
цитаты не нужны:
if [[ -f $file ]]
-
Поскольку это синтаксическая функция, она позволяет использовать операторы &&
и ||
для булевых тестов и <
и >
для сравнения строк. [
не может это сделать, потому что это регулярная команда, а &&
, ||
, <
и >
не передаются в обычные команды в качестве аргументов командной строки.
-
У этого есть замечательный оператор =~
для выполнения матчей регулярных выражений. С помощью [
вы можете написать
if [ "$answer" = y -o "$answer" = yes ]
С [[
вы можете записать это как
if [[ $answer =~ ^y(es)?$ ]]
Он даже позволяет вам получить доступ к захваченным группам, которые он хранит в BASH_REMATCH
. Например, ${BASH_REMATCH[1]}
будет "es", если вы набрали полное "да" выше.
-
Вы получаете бесплатную подборку шаблонов aka globbing. Может быть, вы менее строги в том, как вводить "да". Может быть, вы в порядке, если пользователь вводит y-anything. Покрывало:
if [[ $ANSWER = y* ]]
Имейте в виду, что это расширение bash, поэтому, если вы пишете sh-совместимые скрипты, вам нужно придерживаться [
. Убедитесь, что у вас есть #!/bin/bash
строка shebang для вашего script, если вы используете двойные скобки.
См. также
Ответ 2
-
[
совпадает с встроенным test
и работает как двоичный test
(мужской тест)
- работает примерно так же, как
[
во всех других оболочках sh на многих UNIX-подобных средах.
- поддерживает только одно условие. Несколько тестов с операторами bash
&&
и ||
должны быть в отдельных скобках.
- не поддерживает оператор 'not'. Чтобы инвертировать условие, используйте
!
вне первой скобки, чтобы использовать средство оболочки для инвертирования значений возвращаемых команд.
-
==
и !=
- литеральные сравнения строк
-
[[
является bash
- bash -специфичен, хотя другие оболочки могут реализовывать аналогичные конструкции. Не ожидайте этого в старой школе UNIX sh.
-
==
и !=
применять правила соответствия шаблону bash, см. "Согласование шаблонов" в man bash
- имеет оператор соответствия
=~
регулярных выражений
- позволяет использовать круглые скобки и логические операторы
!
, &&
и ||
в скобках для объединения подвыражений
Кроме того, они довольно похожи - большинство отдельных тестов работают одинаково между ними, вещи становятся интересными только тогда, когда вам нужно комбинировать разные тесты с логическими операциями AND/OR/NOT.
Ответ 3
В bash, в отличие от [
, [[
предотвращает разделение слов значений переменных.
Ответ 4
Самым важным отличием будет ясность вашего кода. Да, да, сказанное выше верно, но [[]] приводит ваш код в соответствие с тем, что вы ожидаете на языках высокого уровня, особенно в отношении AND (&&), OR (||) и NOT (!) операторы. Таким образом, когда вы перемещаетесь между системами и языками, вы сможете быстрее интерпретировать сценарий, что облегчает вашу жизнь. Получите подробности из хорошего справочника по UNIX/Linux. Вы можете найти некоторые мелочи полезными в определенных обстоятельствах, но вы всегда будете ценить ясный код! Какой фрагмент сценария вы бы предпочли прочитать? Даже вне контекста, первый выбор легче читать и понимать.
if [[ -d $newDir && -n $(echo $newDir | grep "^${webRootParent}") && -n $(echo $newDir | grep '/$') ]]; then ...
или же
if [ -d "$newDir" -a -n "$(echo "$newDir" | grep "^${webRootParent}")" -a -n "$(echo "$newDir" | grep '/$')" ]; then ...