лучшие скобки оболочки для использования для if / then операторов [duplicate]

Попробуйте

SELECT OrderId, 
       COUNT(*) ItemCount,
       SUM(CASE WHEN PriceType = 'CopyCost' THEN Price ELSE 0 END) TotalCopyCost,
       SUM(CASE WHEN PriceType = 'FullPrice' THEN Price ELSE 0 END) TotalFullPrice
  FROM OrderDetails
 GROUP BY OrderId

SQLFiddle

115
задан codeforester 25 April 2018 в 02:00
поделиться

6 ответов

Single [] - это тесты условий, совместимые с командами, совместимыми с командами.

Двойной [[]] является расширением стандарта [] и поддерживаются bash и другими оболочками (например, zsh, ksh). Они поддерживают дополнительные операции (а также стандартные операции posix). Например: || вместо -o и соответствия регулярных выражений с =~. Более полный список различий можно найти в разделе bash manual по условным конструкциям .

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

128
ответ дан cmh 15 August 2018 в 17:08
поделиться
  • 1
    Я бы добавил, что если ваш скрипт не начинается с shebang, который явно запрашивает оболочку, которая поддерживает [[ ]] (например, bash с #!/bin/bash или #!/usr/bin/env bash), вы должны использовать переносную опцию. Сценарии, которые предполагают, что / bin / sh поддерживают такие расширения, будут разбиваться на операционные системы, такие как недавние выпуски Debian и Ubuntu, где это не так. – Gordon Davisson 8 August 2018 в 21:21

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

if [[ $1 =~ "foo.*bar" ]] ; then

(если версия bash, которую вы используете, поддерживает этот синтаксис)

1
ответ дан asf107 15 August 2018 в 17:08
поделиться
  • 1
    Кроме того, что вы процитировали шаблон, поэтому теперь он рассматривается как буквальная строка. – ormaaj 24 November 2012 в 20:05
  • 2
    очень верно. иногда это меня раздражает :) – asf107 27 November 2012 в 20:36

Различия в поведении

Протестировано в Bash 4.3.11:

  • POSIX vs Расширение Bash: [ - POSIX [[ is расширение Bash
  • регулярная команда vs magic [ - это просто регулярная команда со странным именем. ] - это просто аргумент [, который не позволяет использовать дополнительные аргументы. Ubuntu 16.04 фактически имеет исполняемый файл для него в /usr/bin/[, предоставленный coreutils, но встроенная версия bash имеет приоритет. Ничто не изменяется в том, как Bash анализирует команду. В частности, < является перенаправлением, && и || объединяют несколько команд, ( ) генерирует подоболочки, если не экранируется \, и расширение слова происходит, как обычно. [[ X ]] представляет собой единую конструкцию, которая делает X разыгранным магическим образом. <, &&, || и () обрабатываются специально, а правила разделения слов различны. Существуют также дополнительные различия, такие как = и =~. В Bashese: [ - встроенная команда, а [[ - ключевое слово: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and- shell-keyword
  • < [[ a < b ]]: лексикографическое сравнение [ a \< b ]: То же, что и выше. \, или же перенаправление, как и для любой другой команды. Расширение Bash. Я не мог найти альтернативу POSIX, см. . Как проверить строки для меньших или равных?
  • && и || [[ a = a && b = b ]]: true, logical и [ a = a && b = b ]: синтаксическая ошибка, && проанализирована как разделитель команды AND cmd1 && cmd2 [ a = a -a b = b ]: эквивалентна, но устарела POSIX [ a = a ] && [ b = b ]: рекомендация POSIX
  • ( [[ (a = a || a = b) && a = b ]]: false [ ( a = a ) ]: синтаксическая ошибка, () интерпретируется как подоболочка [ \( a = a -o a = b \) -a a = b ]: эквивалентна, но () устарела с помощью POSIX ([ a = a ] || [ a = b ]) && [ a = b ] Рекомендация POSIX
  • разбиение слова x='a b'; [[ $x = 'a b' ]]: true, кавычки не нужны x='a b'; [ $x = 'a b' ]: синтаксическая ошибка, расширяется до [ a b = 'a b' ] x='a b'; [ "$x" = 'a b' ]: эквивалентна
  • = [[ ab = a? ]]: true, потому что она соответствует шаблону (* ? [ являются волшебными). Не расширяет glob для файлов в текущем каталоге. [ ab = a? ]: a? glob расширяется. Так может быть истинным или ложным в зависимости от файлов в текущем каталоге. [ ab = a\? ]: false, а не расширение glob = и == одинаковы для обоих [ и [[, но == является расширением Bash. printf 'ab' | grep -Eq 'a.': эквивалент POSIX ERE [[ ab =~ 'ab?' ]]: false, теряет магию с помощью '' [[ ab? =~ 'ab?' ]]: true
  • =~ [[ ab =~ ab? ]]: true, расширенное регулярное выражение POSIX match, ? не glob expand [ a =~ a ]: синтаксическая ошибка printf 'ab' | grep -Eq 'ab?': эквивалент POSIX

Рекомендация

Я предпочитаю всегда использовать [].

Есть эквиваленты POSIX для каждой конструкции [[ ]], которую я видел.

Если вы используете [[ ]], вы:

  • потеряете переносимость
  • заставляют читателя изучать тонкости другого расширения bash. [ - это просто регулярная команда со странным именем, никакая специальная семантика не задействована.
51
ответ дан Ciro Santilli 新疆改造中心 六四事件 法轮功 15 August 2018 в 17:08
поделиться
  • 1
    & quot; Существуют эквиваленты POSIX для каждой конструкции [[]], которую я видел. & quot; То же самое можно сказать о любом языке Turing Complete на лице планеты. – A. Rick 16 August 2016 в 10:36
  • 2
    @ A.Rick, который будет правильным ответом на все «Как сделать X в языке Y». SO вопросы :-) Конечно, есть «удобно». неявный в этом утверждении. – Ciro Santilli 新疆改造中心 六四事件 法轮功 16 August 2016 в 10:39
  • 3
    Фантастическое резюме. Спасибо за попытку. Однако я не согласен с этой рекомендацией. Это переносимость по сравнению с более последовательным и мощным синтаксисом. Если вы можете потребовать bash & gt; 4 в своих средах, рекомендуется использовать синтаксис [[]]. – Alkaline 5 September 2016 в 13:07
  • 4
    @Downvoters, пожалуйста, объясните, чтобы я мог узнать и улучшить информацию :-) – Ciro Santilli 新疆改造中心 六四事件 法轮功 12 January 2017 в 17:34
  • 5
    Отличный ответ, но я думаю, что рекомендация : всегда использовать [] следует читать как . Мои предпочтения : используйте [], если вы не хотите потерять переносимость. Как указано здесь : Если переносимость / соответствие POSIX или BourneShell вызывает беспокойство, следует использовать старый синтаксис. Если, с другой стороны, сценарий требует BASH, Zsh или KornShell, новый синтаксис обычно более гибкий, но не обязательно обратно совместимый. Я бы предпочел пойти с [[ ab =~ ab? ]], если можно, и не беспокоюсь о обратная совместимость, чем printf 'ab' | grep -Eq 'ab?' – archemiro 23 April 2017 в 15:33

[[ является ключевым словом bash, аналогичным (но более мощным, чем) командой [.

См.

http://mywiki.wooledge.org/BashFAQ/031 и http://mywiki.wooledge.org/BashGuide / TestsAndConditionals

Если вы не пишете POSIX sh, мы рекомендуем [[.

8
ответ дан codeforester 15 August 2018 в 17:08
поделиться

Внутри отдельных скобок для теста условий (т. е. [...]) некоторые операторы, такие как single =, поддерживаются всеми оболочками, тогда как использование оператора == не поддерживается некоторыми из старых оболочек.

Внутренние двойные скобки для теста условий (т. е. [[...]]), нет никакой разницы между использованием = или == в старых или новых оболочках.

Изменить : Я должен также отметить, что: В bash всегда используйте двойные скобки [[...]], если это возможно, потому что это безопаснее, чем отдельные скобки. Я проиллюстрирую, почему в следующем примере:

if [ $var == "hello" ]; then

, если $ var оказывается пустым / пустым, то это то, что видит скрипт:

if [ == "hello" ]; then

, который будет сломайте свой скрипт. Решение состоит в том, чтобы либо использовать двойные скобки, либо всегда помнить о том, чтобы помещать кавычки вокруг ваших переменных ("$var"). Двойные скобки - лучшая защитная практика кодирования.

14
ответ дан sampson-chen 15 August 2018 в 17:08
поделиться

Руководство Bash говорит:

При использовании с [[, операторы '& lt;' и '>' сортируют лексикографически с использованием текущей локали. Команда test использует порядок ASCII.

(Команда тестирования идентична [])

1
ответ дан user5500105 15 August 2018 в 17:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: