Простые логические операторы в Bash
у меня есть несколько переменных, и я хочу проверить следующее условие (написанное словами, а затем моя неудачная попытка написания сценариев bash):
if varA EQUALS 1 AND ( varB EQUALS "t1" OR varB EQUALS "t2" ) then
do something
done.
и в моей неудачной попытке, я придумал:
if (($varA == 1)) && ( (($varB == "t1")) || (($varC == "t2")) );
then
scale=0.05
fi
5 ответов:
то, что вы написали на самом деле почти работает (это будет работать, если все переменные были цифры), но это не идиоматическое пути.
(…)скобках указать subshell. То, что внутри них, не является выражением, как во многих других языках. Это список команд (так же, как и вне скобок). Эти команды выполняются в отдельном подпроцессе, поэтому любое перенаправление, назначение и т. д. выполненный внутри скобок не имеет никакого эффекта вне скобок.
- с ведущим знаком доллара,
$(…)- это команду: внутри круглых скобок есть команда, и вывод из команды используется как часть командной строки (после дополнительных расширений, если подстановка не находится между двойными кавычками, но это другая история).{ … }фигурные скобки похожи на круглые скобки в том, что они группируют команды, но они влияют только на синтаксический анализ, а не группировка. Программа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]][ … ]одиночные скобки-это альтернативная форма условных выражений с большим количеством причуд (но более старая и более портативная). Не пишите сейчас; начните беспокоиться о них, когда вы найдете сценарии, которые их содержат.это идиоматический способ написать свой тест в Баш:
if [[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]; thenЕсли вам нужна переносимость на другие оболочки, это будет так (Обратите внимание на дополнительные цитаты и отдельные наборы скобок вокруг каждого отдельного теста):
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
очень близко
if [[ $varA -eq 1 ]] && [[ $varB == 't1' || $varC == 't2' ]]; then scale=0.05 fiдолжны работать.
разборки
[[ $varA -eq 1 ]]- это целочисленное сравнение где как
$varB == 't1'- это сравнение строк. в противном случае, я просто группирую сравнения правильно.
двойные квадратные скобки разделяют условное выражение. И, я нахожу следующее, чтобы быть хорошим чтением на эту тему:"(IBM) Demystify test, [, [[, ((, и если-то-еще"
очень портативная версия (даже для legacy Bourne shell):
if [ "$varA" = 1 -a \( "$varB" = "t1" -o "$varB" = "t2" \) ] then do-something fiэто имеет дополнительное качество запуска не более одного подпроцесса (который является процессом '['), независимо от вкуса оболочки.
заменить " = "на"- eq", если переменные содержат числовые значения, например
- 3-eq 03 верно, но
- 3 = 03 является ложным. (сравнение строк)
if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ] then echo STR is empty but should have a value. fi
вот код для короткой версии оператора if-then-else:
( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok"обратите внимание на следующее:
||и&&операнды внутри условия if (т. е. между круглыми скобками) являются логическими операндами (или/и)
||и&&операнды снаружи, если условие означает тогда/elseпрактически в заявлении говорится:
если (a=1 или b=2), то " ок" еще "НОК"
Comments