Простые логические операторы в 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}
это расширения параметр, расширяясь до значения переменной, с возможными дополнительными преобразованиями.
- с ведущим знаком доллара,
-
((…))
двойные скобки окружают арифметические инструкции, что is, вычисление на целых числах, с синтаксисом, напоминающим другие языки программирования. Этот синтаксис в основном используется для назначений и в conditionals.- тот же синтаксис используется в арифметических выражениях
$((…))
, которые расширяются до целочисленного значения выражения.
- тот же синтаксис используется в арифметических выражениях
-
[[ … ]]
двойные скобки окружают условные выражения. Условные выражения в основном построены на операторы например-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-false. (сравнение строк)
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), то " ok" иначе "НОК"