我有几个变量,我想检查以下条件(写在文字,然后我在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
我有几个变量,我想检查以下条件(写在文字,然后我在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
非常接近
if [[ $varA -eq 1 ]] && [[ $varB == 't1' || $varC == 't2' ]];
then
scale=0.05
fi
应该工作。
把它分解
[[ $varA -eq 1 ]]
是整数比较 而
$varB == 't1'
是字符串比较。 否则,我只是正确地分组比较。
双方括号分隔条件表达式。并且,我发现下面是关于这个主题的一个很好的阅读:“(IBM) Demystify test, [, [[, ((, And if-then-else)”
你所写的几乎是可行的(如果所有变量都是数字的话),但这根本不是一个惯用的方法。
(…) parentheses indicate a subshell. What's inside them isn't an expression like in many other languages. It's a list of commands (just like outside parentheses). These commands are executed in a separate subprocess, so any redirection, assignment, etc. performed inside the parentheses has no effect outside the parentheses. With a leading dollar sign, $(…) is a command substitution: there is a command inside the parentheses, and the output from the command is used as part of the command line (after extra expansions unless the substitution is between double quotes, but that's another story). { … } braces are like parentheses in that they group commands, but they only influence parsing, not grouping. The program x=2; { x=4; }; echo $x prints 4, whereas x=2; (x=4); echo $x prints 2. (Also braces require spaces around them and a semicolon before closing, whereas parentheses don't. That's just a syntax quirk.) With a leading dollar sign, ${VAR} is a parameter expansion, expanding to the value of a variable, with possible extra transformations. ((…)) double parentheses surround an arithmetic instruction, that is, a computation on integers, with a syntax resembling other programming languages. This syntax is mostly used for assignments and in conditionals. The same syntax is used in arithmetic expressions $((…)), which expand to the integer value of the expression. [[ … ]] double brackets surround conditional expressions. Conditional expressions are mostly built on operators such as -n $variable to test if a variable is empty and -e $file to test if a file exists. There are also string equality operators: "$string1" == "$string2" (beware that the right-hand side is a pattern, e.g. [[ $foo == a* ]] tests if $foo starts with a while [[ $foo == "a*" ]] tests if $foo is exactly a*), and the familiar !, && and || operators for negation, conjunction and disjunction as well as parentheses for grouping. Note that you need a space around each operator (e.g. [[ "$x" == "$y" ]], not [[ "$x"=="$y" ]]), and a space or a character like ; both inside and outside the brackets (e.g. [[ -n $foo ]], not [[-n $foo]]). [ … ] single brackets are an alternate form of conditional expressions with more quirks (but older and more portable). Don't write any for now; start worrying about them when you find scripts that contain them.
这是在bash中编写测试的惯用方法:
if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then
如果您需要可移植性到其他shell,则可以采用这种方法(请注意每个单独测试周围的附加引号和单独的括号,以及使用传统的=运算符而不是ksh/bash/zsh ==变体):
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ]
then
echo STR is empty but should have a value.
fi
一个非常便携的版本(甚至是遗留的bourne shell):
if [ "$varA" = 1 -a \( "$varB" = "t1" -o "$varB" = "t2" \) ]
then do-something
fi
这有一个额外的特性,即最多只运行一个子进程(即process[),无论shell类型如何。
如果变量包含数值,则将=替换为-eq。
3 -eq 03是正确的,但是 3 = 03为假。(字符串比较)
下面是if-then-else语句的简短版本:
( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok"
注意以下几点:
if条件中的||和&&操作数(即圆括号之间)是逻辑操作数(或/和) if条件外的||和&&操作数表示then/else
实际上,该声明说:
If (a=1或b=2) then "ok" else "nok"