То, что вы написали, на самом деле почти работает (это будет работать, если бы все переменные были числами), но это совсем не идиоматический способ.
(…)
круглые скобки обозначают подоболочку . То, что внутри них, не является выражением, как во многих других языках. Это список команд (как и в скобках). Эти команды выполняются в отдельном подпроцессе, поэтому любое перенаправление, присваивание и т. Д., Выполняемые внутри скобок, не влияют за пределы скобок.
- С ведущим знаком доллара
$(…)
- подстановка команды : в скобках есть команда, а вывод команды используется как часть командной строки (после дополнительных расширений, если подстановка не заключена в двойные кавычки, но это уже другая история ) ,
{ … }
Скобки подобны скобкам в том смысле, что они группируют команды, но они влияют только на синтаксический анализ, а не на группировку. Программа x=2; { x=4; }; echo $x
печатает 4, а x=2; (x=4); echo $x
печатает 2. (Также скобки требуют пробелов вокруг них и точки с запятой перед закрытием, тогда как круглые скобки - нет. Это просто синтаксическая ошибка).
- С ведущим знаком доллара,
${VAR}
это расширение параметра , расширяющееся до значения переменной, с возможными дополнительными преобразованиями.
((…))
двойные скобки окружают арифметическую инструкцию , то есть вычисление на целых числах, с синтаксисом, похожим на другие языки программирования. Этот синтаксис в основном используется для назначений и в условных выражениях.
- Тот же синтаксис используется в арифметических выражениях
$((…))
, которые расширяются до целочисленного значения выражения.
[[ … ]]
двойные скобки окружают условные выражения . Условные выражения в основном построены на операторах, таких как -n $variable
проверка, является ли переменная пустой, и -e $file
проверка, существует ли файл. Существуют также операторы равенства строк: "$string1" == "$string2"
(имейте в виду, что правая часть является шаблоном, например, [[ $foo == a* ]]
тесты, если $foo
начинается с, в a
то время как [[ $foo == "a*" ]]
тесты, если $foo
точно a*
), и знакомые !
, &&
и ||
операторы для отрицания, соединения и дизъюнкции, а также круглые скобки для группировки. Обратите внимание, что вам нужен пробел вокруг каждого оператора (например [[ "$x" == "$y" ]]
, не [[ "$x"=="$y" ]]
), а также пробел или символ, как ;
внутри, так и вне скобок (например [[ -n $foo ]]
, не[[-n $foo]]
).
[ … ]
одиночные скобки представляют собой альтернативную форму условных выражений с большим количеством причуд (но более старых и более переносимых). Не пишите пока что; начать беспокоиться о них, когда вы найдете сценарии, которые их содержат.
Это идиоматический способ написать свой тест на bash:
if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then
Если вам нужна переносимость на другие оболочки, это будет правильным способом (обратите внимание на дополнительные кавычки и отдельные наборы скобок вокруг каждого отдельного теста и использование традиционного =
оператора, а не ==
варианта ksh / bash / zsh ):
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
Жиль "ТАК - перестань быть злым"
источник
==
чтобы отличить сравнение от присвоения переменной (что также=
)[[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]
, не запускают подпроцесс, хотя первый пункт маркировки прямо говорит: «То, что внутри [круглых скобок] , не является выражением, как во многих других языках» - но это, безусловно, здесь! Это, вероятно, очевидно для опытного мастера Bash, но даже не для меня, сразу. Путаница может возникнуть из- за того , что в выражении могут использоваться одиночные скобкиif
, а не в выражениях в двойных скобках.==
самом деле не «более идиоматичен», чем=
. Они имеют то же значение, но==
это вариант ksh, также доступный в bash и zsh, тогда как=
является переносимым. На самом деле нет никаких преимуществ в использовании==
, и это не работает в простой ш.==
внутри[[ … ]]
, если хотите, но=
у вас есть преимущество в том, что вы тоже работаете[ … ]
, поэтому я не рекомендую вообще использовать его==
.очень близко
должно сработать.
ломая это
целочисленное сравнение, где как
это сравнение строк. в противном случае я просто правильно группирую сравнения.
Двойные квадратные скобки ограничивают условное выражение. И я нахожу следующее чтение этой темы хорошим: «(IBM) Demystify test, [, [[, ((и if-then-else»)
источник
't1'
не нужно, верно? Потому что в отличие от арифметических инструкций в двойных скобках, гдеt1
будет переменная,t1
в условном выражении в двойных скобках есть просто литеральная строка. Т.е.[[ $varB == 't1' ]]
точно так же, как[[ $varB == t1 ]]
, верно?Очень портативная версия (даже для устаревшей оболочки Bourne):
Это имеет дополнительное качество запуска только одного подпроцесса (который является процессом
[
), независимо от вида оболочки.Замените
=
на,-eq
если переменные содержат числовые значения, например3 -eq 03
верно, но3 = 03
ложно (сравнение строк)источник
Вот код для короткой версии оператора if-then-else:
Обратите внимание на следующее:
||
и&&
операнды внутри, если условие (т.е. между круглыми скобками) являются логическими операндами (или / и)||
и&&
операнды снаружи, если условие означает то / ещеПрактически в заявлении говорится:
если (a = 1 или b = 2), тогда «ок», иначе «нок»
источник
( ... )
создает подоболочку. Может хотеть использовать скобки{ ... }
вместо этого. Любое состояние, созданное в подоболочке, не будет видно в вызывающей стороне.источник