Конструкции ((…)) и [[…]]

03.03.2018

Теги: BashCLILinuxКоманда

Конструкция ((…)) позволяет работать с целыми числами:

$ var=$(( 10 + 5 ))
$ echo $var
15
$ (( var = var + 1 )) # внутри ((…)) переменные можно использовать без знака $ …
$ echo $var
16
$ echo $(( $var * 2 )) # … но можно и со знаком $
32

Умеет работать с логическими операторами:

$ var=50
$ result=$(( var >= 0 && var <= 100 )) # результат вычисления выражения
$ echo $result
1
$ result=$(( var >= 0 && var <= 10 )) # результат вычисления выражения
$ echo $result
0

Результат кажется странным, но в первом случае это единица (истина), а во втором случае ноль (ложь). Но при этом код возврата в первом случае будет ноль (истина), а код возврата во втором случае будет единица (ложь).

Так сложилось исторически в shell-скриптах. Если программа выполнилась успешно, она возвращает ноль. Если при выполнении возникли ошибки — программа возвращает код ошибки. Просто не надо путать код возврата и результат вычисления.

Внутри конструкции ((…)) все работает, как в языке програмирования C. Если логический результат ложь — это ноль, если логический результат истина — это единица. Мы используем конструкцию $((…)), чтобы получить этот результат.

$ var=50
$ (( var >= 0 && var <= 100 )) # код возврата конструкции ((...))
$ echo $?
0
$ (( var >= 0 && var <= 10 )) # код возврата конструкции ((...))
$ echo $?
1

Ее часто используют в операторе if, когда одновременно нужна работа с целыми числами + есть логические выражения. Если результат логического выражения будет «истина» — код возврата будет нулевым, для if это означает «истина»:

if ((var == x * 3 + y * 2)) ; then
  echo "yes"
fi

Для группировки элементов можно использовать круглые скобки:

$ echo $(( i = (i + 10) * j )) # внутри ((…)) можно использовать пробелы перед и после =

Таким образом, конструкция ((…)) поддерживает:

  • операторы сравнения ==, !=, >, <, >=, <=
  • математические операции +, -, *, /, **, %
  • логические операторы &&, ||, !
  • круглые скобки (…)

Как и в случае с ((…)), конструкция [[…]] позволяет использовать более естественный синтаксис для проверки файлов и сравнения строк. Можно использовать &&, ||, < и > и круглые скобки (…) для группировки элементов:

$ [[ ( -d "$HOME" ) && ( -w "$HOME" ) ]] && echo "home is a writable directory"

Операторы < и > используются для сравнения строк, а не чисел. Для сравнения чисел надо использовать ((…)), например ((foo > 7)).

Можно сказать, что конструкция [[…]] является расширенной версией команды test: она умеет делать все то же самое + позволяет использовать &&, || и круглые скобки (…) без обратных слэшей.

Кроме того, конструкция [[…]] поддерживает регулярные выражения:

[[ string =~ pattern ]]

Статус выхода устанавливается в 0, если регулярное выражение совпало со строкой, и в 1 — если не совпало. Значение подвыражения, заключённого в скобки, можно получить через переменную BASH_REMATCH[@], например:

REGEXP='foo(bar)bl(.*)'
if [[ "abcfoobarbletch" =~ $REGEXP ]] ; then
    echo "Регулярное выражение совпало со строкой!" 
    echo "$BASH_REMATCH"      # выводит: foobarbletch 
    echo "${BASH_REMATCH[@]}" # выводит: foobarbletch bar etch
    echo "${BASH_REMATCH[1]}" # выводит: bar 
    echo "${BASH_REMATCH[2]}" # выводит: etch 
fi

Обратите внимание, что внутри [[…]] регулярное выражение не должно заключаться в кавычки. Если регулярное выражение содержит пробелы, то нужно поместить его в переменную, как сделано в примере выше.

По аналогии с ((…)), конструкция [[…]] оценивает выражение и устанавливает статус выдачи равный 1, если выражение ложно, или статус выдачи равный 0, если выражение истинно.

Поиск: Bash • CLI • Linux • Команда

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.