我有几个变量,我想检查以下条件(用文字写出来,然后是我在 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
你所写的实际上几乎可以工作(如果所有变量都是数字,它就会工作),但这根本不是一种惯用的方式。
(…)
括号表示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]]
) [ … ]
单括号是条件表达式的另一种形式,具有更多怪癖(但更旧且更便携)。暂时不要写;当您发现包含它们的脚本时,请开始担心它们。这是在 bash 中编写测试的惯用方法:
if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then
如果您需要移植到其他 shell,可以这样做:
if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
(请注意每个单独测试周围的额外引用和单独的括号组,以及使用传统的
=
运算符而不是 ksh/bash/zsh ==
变体)
非常接近。
if [[ $varA -eq 1 ]] && [[ $varB == 't1' || $varC == 't2' ]];
then
scale=0.05
fi
应该可以。
分解它,
[[ $varA -eq 1 ]]
是整数比较, 而
$varB == 't1'
是字符串比较。 否则,我只是正确地对比较进行分组。
双方括号界定条件表达式。而且,我发现以下内容是关于该主题的好读物:“(IBM)揭秘测试,[,[[,((和 if-then-else”
一个非常便携的版本(甚至对于旧版Bourne shell):
if [ "$varA" = 1 -a \( "$varB" = "t1" -o "$varB" = "t2" \) ]
then do-something
fi
这具有最多仅运行一个子进程(即进程
[
)的额外质量,无论 shell 风格如何。
如果变量包含数值,则将
=
替换为 -eq
,例如
3 -eq 03
是真的,但是3 = 03
是假的。 (字符串比较)这是 if-then-else 语句的简短版本的代码:
( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok"
注意以下事项:
条件内(即圆括号之间)的
||
和&&
操作数是逻辑操作数(或/和)
||
和 &&
位于 if 条件之外的操作数表示 then/else
实际上,声明说:
if (a=1 或 b=2) then "ok" else "nok"
if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ]
then
echo STR is empty but should have a value.
fi